add freeglut (work in progress)

This commit is contained in:
ejcoumans 2007-12-14 01:46:49 +00:00
parent 961c38269b
commit 38349b5af4
29 changed files with 23217 additions and 0 deletions

27
Extras/freeglut/COPYING Normal file
View File

@ -0,0 +1,27 @@
Freeglut Copyright
------------------
Freeglut code without an explicit copyright is covered by the following
copyright:
Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
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 or substantial portions of the Software.
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.
Except as contained in this notice, the name of Pawel W. Olszta shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Pawel W. Olszta.

View File

@ -0,0 +1,22 @@
#ifndef __FREEGLUT_H__
#define __FREEGLUT_H__
/*
* freeglut.h
*
* The freeglut library include file
*
* 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.
*/
#include "freeglut_std.h"
#include "freeglut_ext.h"
/*** END OF FILE ***/
#endif /* __FREEGLUT_H__ */

View File

@ -0,0 +1,135 @@
#ifndef __FREEGLUT_EXT_H__
#define __FREEGLUT_EXT_H__
/*
* freeglut_ext.h
*
* The non-GLUT-compatible extensions to the freeglut library include file
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 2 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.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* GLUT API Extension macro definitions -- behaviour when the user clicks on an "x" to close a window
*/
#define GLUT_ACTION_EXIT 0
#define GLUT_ACTION_GLUTMAINLOOP_RETURNS 1
#define GLUT_ACTION_CONTINUE_EXECUTION 2
/*
* Create a new rendering context when the user opens a new window?
*/
#define GLUT_CREATE_NEW_CONTEXT 0
#define GLUT_USE_CURRENT_CONTEXT 1
/*
* Direct/Indirect rendering context options (has meaning only in Unix/X11)
*/
#define GLUT_FORCE_INDIRECT_CONTEXT 0
#define GLUT_ALLOW_DIRECT_CONTEXT 1
#define GLUT_TRY_DIRECT_CONTEXT 2
#define GLUT_FORCE_DIRECT_CONTEXT 3
/*
* GLUT API Extension macro definitions -- the glutGet parameters
*/
#define GLUT_ACTION_ON_WINDOW_CLOSE 0x01F9
#define GLUT_WINDOW_BORDER_WIDTH 0x01FA
#define GLUT_WINDOW_HEADER_HEIGHT 0x01FB
#define GLUT_VERSION 0x01FC
#define GLUT_RENDERING_CONTEXT 0x01FD
#define GLUT_DIRECT_RENDERING 0x01FE
/*
* New tokens for glutInitDisplayMode.
* Only one GLUT_AUXn bit may be used at a time.
* Value 0x0400 is defined in OpenGLUT.
*/
#define GLUT_AUX1 0x1000
#define GLUT_AUX2 0x2000
#define GLUT_AUX3 0x4000
#define GLUT_AUX4 0x8000
/*
* Process loop function, see freeglut_main.c
*/
FGAPI void FGAPIENTRY glutMainLoopEvent( void );
FGAPI void FGAPIENTRY glutLeaveMainLoop( void );
/*
* Window-specific callback functions, see freeglut_callbacks.c
*/
FGAPI void FGAPIENTRY glutMouseWheelFunc( void (* callback)( int, int, int, int ) );
FGAPI void FGAPIENTRY glutCloseFunc( void (* callback)( void ) );
FGAPI void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) );
/* A. Donev: Also a destruction callback for menus */
FGAPI void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) );
/*
* State setting and retrieval functions, see freeglut_state.c
*/
FGAPI void FGAPIENTRY glutSetOption ( GLenum option_flag, int value ) ;
/* A.Donev: User-data manipulation */
FGAPI void* FGAPIENTRY glutGetWindowData( void );
FGAPI void FGAPIENTRY glutSetWindowData(void* data);
FGAPI void* FGAPIENTRY glutGetMenuData( void );
FGAPI void FGAPIENTRY glutSetMenuData(void* data);
/*
* Font stuff, see freeglut_font.c
*/
FGAPI int FGAPIENTRY glutBitmapHeight( void* font );
FGAPI GLfloat FGAPIENTRY glutStrokeHeight( void* font );
FGAPI void FGAPIENTRY glutBitmapString( void* font, const unsigned char *string );
FGAPI void FGAPIENTRY glutStrokeString( void* font, const unsigned char *string );
/*
* Geometry functions, see freeglut_geometry.c
*/
FGAPI void FGAPIENTRY glutWireRhombicDodecahedron( void );
FGAPI void FGAPIENTRY glutSolidRhombicDodecahedron( void );
FGAPI void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale ) ;
FGAPI void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale ) ;
FGAPI void FGAPIENTRY glutWireCylinder( GLdouble radius, GLdouble height, GLint slices, GLint stacks);
FGAPI void FGAPIENTRY glutSolidCylinder( GLdouble radius, GLdouble height, GLint slices, GLint stacks);
/*
* Extension functions, see freeglut_ext.c
*/
typedef void (*GLUTproc)();
FGAPI GLUTproc FGAPIENTRY glutGetProcAddress( const char *procName );
#ifdef __cplusplus
}
#endif
/*** END OF FILE ***/
#endif /* __FREEGLUT_EXT_H__ */

View File

@ -0,0 +1,578 @@
#ifndef __FREEGLUT_STD_H__
#define __FREEGLUT_STD_H__
/*
* freeglut_std.h
*
* The GLUT-compatible part of the freeglut library include file
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 2 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.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* Under windows, we have to differentiate between static and dynamic libraries
*/
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__)
/* #pragma may not be supported by some compilers.
* Discussion by FreeGLUT developers suggests that
* Visual C++ specific code involving pragmas may
* need to move to a separate header. 24th Dec 2003
*/
# define WIN32_LEAN_AND_MEAN
# define NO_MIN_MAX
# include <windows.h>
# undef min
# undef max
/* Windows static library */
#define FREEGLUT_STATIC
# ifdef FREEGLUT_STATIC
# define FGAPI
# define FGAPIENTRY
/* Link with Win32 static freeglut lib */
# if defined(_MSC_VER)
//# pragma comment (lib, "freeglut_static.lib")
# endif
/* Windows shared library (DLL) */
# else
# if defined(FREEGLUT_EXPORTS)
# define FGAPI __declspec(dllexport)
# else
# define FGAPI __declspec(dllimport)
/* link with Win32 shared freeglut lib */
# if defined(_MSC_VER)
# ifndef _WIN32_WCE
# pragma comment (lib, "freeglut.lib")
# endif
# endif
# endif
# define FGAPIENTRY __stdcall
# endif
/* Drag in other Windows libraries as required by FreeGLUT */
# if defined(_MSC_VER)
# ifndef _WIN32_WCE
# pragma comment (lib, "winmm.lib") /* link Windows MultiMedia lib */
# pragma comment (lib, "user32.lib") /* link Windows user lib */
# pragma comment (lib, "gdi32.lib") /* link Windows GDI lib */
# pragma comment (lib, "opengl32.lib") /* link Microsoft OpenGL lib */
# pragma comment (lib, "glu32.lib") /* link OpenGL Utility lib */
# endif /* _WIN32_WCE */
# endif
#else
/* Non-Windows definition of FGAPI and FGAPIENTRY */
# define FGAPI
# define FGAPIENTRY
#endif
/*
* The freeglut and GLUT API versions
*/
#define FREEGLUT 1
#define GLUT_API_VERSION 4
#define FREEGLUT_VERSION_2_0 1
#define GLUT_XLIB_IMPLEMENTATION 13
/*
* Always include OpenGL and GLU headers
*/
#include <GL/gl.h>
#include <GL/glu.h>
/*
* GLUT API macro definitions -- the special key codes:
*/
#define GLUT_KEY_F1 0x0001
#define GLUT_KEY_F2 0x0002
#define GLUT_KEY_F3 0x0003
#define GLUT_KEY_F4 0x0004
#define GLUT_KEY_F5 0x0005
#define GLUT_KEY_F6 0x0006
#define GLUT_KEY_F7 0x0007
#define GLUT_KEY_F8 0x0008
#define GLUT_KEY_F9 0x0009
#define GLUT_KEY_F10 0x000A
#define GLUT_KEY_F11 0x000B
#define GLUT_KEY_F12 0x000C
#define GLUT_KEY_LEFT 0x0064
#define GLUT_KEY_UP 0x0065
#define GLUT_KEY_RIGHT 0x0066
#define GLUT_KEY_DOWN 0x0067
#define GLUT_KEY_PAGE_UP 0x0068
#define GLUT_KEY_PAGE_DOWN 0x0069
#define GLUT_KEY_HOME 0x006A
#define GLUT_KEY_END 0x006B
#define GLUT_KEY_INSERT 0x006C
/*
* GLUT API macro definitions -- mouse state definitions
*/
#define GLUT_LEFT_BUTTON 0x0000
#define GLUT_MIDDLE_BUTTON 0x0001
#define GLUT_RIGHT_BUTTON 0x0002
#define GLUT_DOWN 0x0000
#define GLUT_UP 0x0001
#define GLUT_LEFT 0x0000
#define GLUT_ENTERED 0x0001
/*
* GLUT API macro definitions -- the display mode definitions
*/
#define GLUT_RGB 0x0000
#define GLUT_RGBA 0x0000
#define GLUT_INDEX 0x0001
#define GLUT_SINGLE 0x0000
#define GLUT_DOUBLE 0x0002
#define GLUT_ACCUM 0x0004
#define GLUT_ALPHA 0x0008
#define GLUT_DEPTH 0x0010
#define GLUT_STENCIL 0x0020
#define GLUT_MULTISAMPLE 0x0080
#define GLUT_STEREO 0x0100
#define GLUT_LUMINANCE 0x0200
/*
* GLUT API macro definitions -- windows and menu related definitions
*/
#define GLUT_MENU_NOT_IN_USE 0x0000
#define GLUT_MENU_IN_USE 0x0001
#define GLUT_NOT_VISIBLE 0x0000
#define GLUT_VISIBLE 0x0001
#define GLUT_HIDDEN 0x0000
#define GLUT_FULLY_RETAINED 0x0001
#define GLUT_PARTIALLY_RETAINED 0x0002
#define GLUT_FULLY_COVERED 0x0003
/*
* GLUT API macro definitions -- fonts definitions
*
* Steve Baker suggested to make it binary compatible with GLUT:
*/
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__)
# define GLUT_STROKE_ROMAN ((void *)0x0000)
# define GLUT_STROKE_MONO_ROMAN ((void *)0x0001)
# define GLUT_BITMAP_9_BY_15 ((void *)0x0002)
# define GLUT_BITMAP_8_BY_13 ((void *)0x0003)
# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *)0x0004)
# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *)0x0005)
# define GLUT_BITMAP_HELVETICA_10 ((void *)0x0006)
# define GLUT_BITMAP_HELVETICA_12 ((void *)0x0007)
# define GLUT_BITMAP_HELVETICA_18 ((void *)0x0008)
#else
/*
* I don't really know if it's a good idea... But here it goes:
*/
extern void* glutStrokeRoman;
extern void* glutStrokeMonoRoman;
extern void* glutBitmap9By15;
extern void* glutBitmap8By13;
extern void* glutBitmapTimesRoman10;
extern void* glutBitmapTimesRoman24;
extern void* glutBitmapHelvetica10;
extern void* glutBitmapHelvetica12;
extern void* glutBitmapHelvetica18;
/*
* Those pointers will be used by following definitions:
*/
# define GLUT_STROKE_ROMAN ((void *) &glutStrokeRoman)
# define GLUT_STROKE_MONO_ROMAN ((void *) &glutStrokeMonoRoman)
# define GLUT_BITMAP_9_BY_15 ((void *) &glutBitmap9By15)
# define GLUT_BITMAP_8_BY_13 ((void *) &glutBitmap8By13)
# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *) &glutBitmapTimesRoman10)
# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *) &glutBitmapTimesRoman24)
# define GLUT_BITMAP_HELVETICA_10 ((void *) &glutBitmapHelvetica10)
# define GLUT_BITMAP_HELVETICA_12 ((void *) &glutBitmapHelvetica12)
# define GLUT_BITMAP_HELVETICA_18 ((void *) &glutBitmapHelvetica18)
#endif
/*
* GLUT API macro definitions -- the glutGet parameters
*/
#define GLUT_WINDOW_X 0x0064
#define GLUT_WINDOW_Y 0x0065
#define GLUT_WINDOW_WIDTH 0x0066
#define GLUT_WINDOW_HEIGHT 0x0067
#define GLUT_WINDOW_BUFFER_SIZE 0x0068
#define GLUT_WINDOW_STENCIL_SIZE 0x0069
#define GLUT_WINDOW_DEPTH_SIZE 0x006A
#define GLUT_WINDOW_RED_SIZE 0x006B
#define GLUT_WINDOW_GREEN_SIZE 0x006C
#define GLUT_WINDOW_BLUE_SIZE 0x006D
#define GLUT_WINDOW_ALPHA_SIZE 0x006E
#define GLUT_WINDOW_ACCUM_RED_SIZE 0x006F
#define GLUT_WINDOW_ACCUM_GREEN_SIZE 0x0070
#define GLUT_WINDOW_ACCUM_BLUE_SIZE 0x0071
#define GLUT_WINDOW_ACCUM_ALPHA_SIZE 0x0072
#define GLUT_WINDOW_DOUBLEBUFFER 0x0073
#define GLUT_WINDOW_RGBA 0x0074
#define GLUT_WINDOW_PARENT 0x0075
#define GLUT_WINDOW_NUM_CHILDREN 0x0076
#define GLUT_WINDOW_COLORMAP_SIZE 0x0077
#define GLUT_WINDOW_NUM_SAMPLES 0x0078
#define GLUT_WINDOW_STEREO 0x0079
#define GLUT_WINDOW_CURSOR 0x007A
#define GLUT_SCREEN_WIDTH 0x00C8
#define GLUT_SCREEN_HEIGHT 0x00C9
#define GLUT_SCREEN_WIDTH_MM 0x00CA
#define GLUT_SCREEN_HEIGHT_MM 0x00CB
#define GLUT_MENU_NUM_ITEMS 0x012C
#define GLUT_DISPLAY_MODE_POSSIBLE 0x0190
#define GLUT_INIT_WINDOW_X 0x01F4
#define GLUT_INIT_WINDOW_Y 0x01F5
#define GLUT_INIT_WINDOW_WIDTH 0x01F6
#define GLUT_INIT_WINDOW_HEIGHT 0x01F7
#define GLUT_INIT_DISPLAY_MODE 0x01F8
#define GLUT_ELAPSED_TIME 0x02BC
#define GLUT_WINDOW_FORMAT_ID 0x007B
#define GLUT_INIT_STATE 0x007C
/*
* GLUT API macro definitions -- the glutDeviceGet parameters
*/
#define GLUT_HAS_KEYBOARD 0x0258
#define GLUT_HAS_MOUSE 0x0259
#define GLUT_HAS_SPACEBALL 0x025A
#define GLUT_HAS_DIAL_AND_BUTTON_BOX 0x025B
#define GLUT_HAS_TABLET 0x025C
#define GLUT_NUM_MOUSE_BUTTONS 0x025D
#define GLUT_NUM_SPACEBALL_BUTTONS 0x025E
#define GLUT_NUM_BUTTON_BOX_BUTTONS 0x025F
#define GLUT_NUM_DIALS 0x0260
#define GLUT_NUM_TABLET_BUTTONS 0x0261
#define GLUT_DEVICE_IGNORE_KEY_REPEAT 0x0262
#define GLUT_DEVICE_KEY_REPEAT 0x0263
#define GLUT_HAS_JOYSTICK 0x0264
#define GLUT_OWNS_JOYSTICK 0x0265
#define GLUT_JOYSTICK_BUTTONS 0x0266
#define GLUT_JOYSTICK_AXES 0x0267
#define GLUT_JOYSTICK_POLL_RATE 0x0268
/*
* GLUT API macro definitions -- the glutLayerGet parameters
*/
#define GLUT_OVERLAY_POSSIBLE 0x0320
#define GLUT_LAYER_IN_USE 0x0321
#define GLUT_HAS_OVERLAY 0x0322
#define GLUT_TRANSPARENT_INDEX 0x0323
#define GLUT_NORMAL_DAMAGED 0x0324
#define GLUT_OVERLAY_DAMAGED 0x0325
/*
* GLUT API macro definitions -- the glutVideoResizeGet parameters
*/
#define GLUT_VIDEO_RESIZE_POSSIBLE 0x0384
#define GLUT_VIDEO_RESIZE_IN_USE 0x0385
#define GLUT_VIDEO_RESIZE_X_DELTA 0x0386
#define GLUT_VIDEO_RESIZE_Y_DELTA 0x0387
#define GLUT_VIDEO_RESIZE_WIDTH_DELTA 0x0388
#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 0x0389
#define GLUT_VIDEO_RESIZE_X 0x038A
#define GLUT_VIDEO_RESIZE_Y 0x038B
#define GLUT_VIDEO_RESIZE_WIDTH 0x038C
#define GLUT_VIDEO_RESIZE_HEIGHT 0x038D
/*
* GLUT API macro definitions -- the glutUseLayer parameters
*/
#define GLUT_NORMAL 0x0000
#define GLUT_OVERLAY 0x0001
/*
* GLUT API macro definitions -- the glutGetModifiers parameters
*/
#define GLUT_ACTIVE_SHIFT 0x0001
#define GLUT_ACTIVE_CTRL 0x0002
#define GLUT_ACTIVE_ALT 0x0004
/*
* GLUT API macro definitions -- the glutSetCursor parameters
*/
#define GLUT_CURSOR_RIGHT_ARROW 0x0000
#define GLUT_CURSOR_LEFT_ARROW 0x0001
#define GLUT_CURSOR_INFO 0x0002
#define GLUT_CURSOR_DESTROY 0x0003
#define GLUT_CURSOR_HELP 0x0004
#define GLUT_CURSOR_CYCLE 0x0005
#define GLUT_CURSOR_SPRAY 0x0006
#define GLUT_CURSOR_WAIT 0x0007
#define GLUT_CURSOR_TEXT 0x0008
#define GLUT_CURSOR_CROSSHAIR 0x0009
#define GLUT_CURSOR_UP_DOWN 0x000A
#define GLUT_CURSOR_LEFT_RIGHT 0x000B
#define GLUT_CURSOR_TOP_SIDE 0x000C
#define GLUT_CURSOR_BOTTOM_SIDE 0x000D
#define GLUT_CURSOR_LEFT_SIDE 0x000E
#define GLUT_CURSOR_RIGHT_SIDE 0x000F
#define GLUT_CURSOR_TOP_LEFT_CORNER 0x0010
#define GLUT_CURSOR_TOP_RIGHT_CORNER 0x0011
#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 0x0012
#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 0x0013
#define GLUT_CURSOR_INHERIT 0x0064
#define GLUT_CURSOR_NONE 0x0065
#define GLUT_CURSOR_FULL_CROSSHAIR 0x0066
/*
* GLUT API macro definitions -- RGB color component specification definitions
*/
#define GLUT_RED 0x0000
#define GLUT_GREEN 0x0001
#define GLUT_BLUE 0x0002
/*
* GLUT API macro definitions -- additional keyboard and joystick definitions
*/
#define GLUT_KEY_REPEAT_OFF 0x0000
#define GLUT_KEY_REPEAT_ON 0x0001
#define GLUT_KEY_REPEAT_DEFAULT 0x0002
#define GLUT_JOYSTICK_BUTTON_A 0x0001
#define GLUT_JOYSTICK_BUTTON_B 0x0002
#define GLUT_JOYSTICK_BUTTON_C 0x0004
#define GLUT_JOYSTICK_BUTTON_D 0x0008
/*
* GLUT API macro definitions -- game mode definitions
*/
#define GLUT_GAME_MODE_ACTIVE 0x0000
#define GLUT_GAME_MODE_POSSIBLE 0x0001
#define GLUT_GAME_MODE_WIDTH 0x0002
#define GLUT_GAME_MODE_HEIGHT 0x0003
#define GLUT_GAME_MODE_PIXEL_DEPTH 0x0004
#define GLUT_GAME_MODE_REFRESH_RATE 0x0005
#define GLUT_GAME_MODE_DISPLAY_CHANGED 0x0006
/*
* Initialization functions, see fglut_init.c
*/
FGAPI void FGAPIENTRY glutInit( int* pargc, char** argv );
FGAPI void FGAPIENTRY glutInitWindowPosition( int x, int y );
FGAPI void FGAPIENTRY glutInitWindowSize( int width, int height );
FGAPI void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode );
FGAPI void FGAPIENTRY glutInitDisplayString( const char* displayMode );
/*
* Process loop function, see freeglut_main.c
*/
FGAPI void FGAPIENTRY glutMainLoop( void );
/*
* Window management functions, see freeglut_window.c
*/
FGAPI int FGAPIENTRY glutCreateWindow( const char* title );
FGAPI int FGAPIENTRY glutCreateSubWindow( int window, int x, int y, int width, int height );
FGAPI void FGAPIENTRY glutDestroyWindow( int window );
FGAPI void FGAPIENTRY glutSetWindow( int window );
FGAPI int FGAPIENTRY glutGetWindow( void );
FGAPI void FGAPIENTRY glutSetWindowTitle( const char* title );
FGAPI void FGAPIENTRY glutSetIconTitle( const char* title );
FGAPI void FGAPIENTRY glutReshapeWindow( int width, int height );
FGAPI void FGAPIENTRY glutPositionWindow( int x, int y );
FGAPI void FGAPIENTRY glutShowWindow( void );
FGAPI void FGAPIENTRY glutHideWindow( void );
FGAPI void FGAPIENTRY glutIconifyWindow( void );
FGAPI void FGAPIENTRY glutPushWindow( void );
FGAPI void FGAPIENTRY glutPopWindow( void );
FGAPI void FGAPIENTRY glutFullScreen( void );
/*
* Display-connected functions, see freeglut_display.c
*/
FGAPI void FGAPIENTRY glutPostWindowRedisplay( int window );
FGAPI void FGAPIENTRY glutPostRedisplay( void );
FGAPI void FGAPIENTRY glutSwapBuffers( void );
/*
* Mouse cursor functions, see freeglut_cursor.c
*/
FGAPI void FGAPIENTRY glutWarpPointer( int x, int y );
FGAPI void FGAPIENTRY glutSetCursor( int cursor );
/*
* Overlay stuff, see freeglut_overlay.c
*/
FGAPI void FGAPIENTRY glutEstablishOverlay( void );
FGAPI void FGAPIENTRY glutRemoveOverlay( void );
FGAPI void FGAPIENTRY glutUseLayer( GLenum layer );
FGAPI void FGAPIENTRY glutPostOverlayRedisplay( void );
FGAPI void FGAPIENTRY glutPostWindowOverlayRedisplay( int window );
FGAPI void FGAPIENTRY glutShowOverlay( void );
FGAPI void FGAPIENTRY glutHideOverlay( void );
/*
* Menu stuff, see freeglut_menu.c
*/
FGAPI int FGAPIENTRY glutCreateMenu( void (* callback)( int menu ) );
FGAPI void FGAPIENTRY glutDestroyMenu( int menu );
FGAPI int FGAPIENTRY glutGetMenu( void );
FGAPI void FGAPIENTRY glutSetMenu( int menu );
FGAPI void FGAPIENTRY glutAddMenuEntry( const char* label, int value );
FGAPI void FGAPIENTRY glutAddSubMenu( const char* label, int subMenu );
FGAPI void FGAPIENTRY glutChangeToMenuEntry( int item, const char* label, int value );
FGAPI void FGAPIENTRY glutChangeToSubMenu( int item, const char* label, int value );
FGAPI void FGAPIENTRY glutRemoveMenuItem( int item );
FGAPI void FGAPIENTRY glutAttachMenu( int button );
FGAPI void FGAPIENTRY glutDetachMenu( int button );
/*
* Global callback functions, see freeglut_callbacks.c
*/
FGAPI void FGAPIENTRY glutTimerFunc( unsigned int time, void (* callback)( int ), int value );
FGAPI void FGAPIENTRY glutIdleFunc( void (* callback)( void ) );
/*
* Window-specific callback functions, see freeglut_callbacks.c
*/
FGAPI void FGAPIENTRY glutKeyboardFunc( void (* callback)( unsigned char, int, int ) );
FGAPI void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) );
FGAPI void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) );
FGAPI void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) );
FGAPI void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutEntryFunc( void (* callback)( int ) );
FGAPI void FGAPIENTRY glutKeyboardUpFunc( void (* callback)( unsigned char, int, int ) );
FGAPI void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutJoystickFunc( void (* callback)( unsigned int, int, int, int ), int pollInterval );
FGAPI void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) );
FGAPI void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) );
FGAPI void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) );
FGAPI void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) );
/*
* State setting and retrieval functions, see freeglut_state.c
*/
FGAPI int FGAPIENTRY glutGet( GLenum query );
FGAPI int FGAPIENTRY glutDeviceGet( GLenum query );
FGAPI int FGAPIENTRY glutGetModifiers( void );
FGAPI int FGAPIENTRY glutLayerGet( GLenum query );
/*
* Font stuff, see freeglut_font.c
*/
FGAPI void FGAPIENTRY glutBitmapCharacter( void* font, int character );
FGAPI int FGAPIENTRY glutBitmapWidth( void* font, int character );
FGAPI void FGAPIENTRY glutStrokeCharacter( void* font, int character );
FGAPI int FGAPIENTRY glutStrokeWidth( void* font, int character );
FGAPI int FGAPIENTRY glutBitmapLength( void* font, const unsigned char* string );
FGAPI int FGAPIENTRY glutStrokeLength( void* font, const unsigned char* string );
/*
* Geometry functions, see freeglut_geometry.c
*/
FGAPI void FGAPIENTRY glutWireCube( GLdouble size );
FGAPI void FGAPIENTRY glutSolidCube( GLdouble size );
FGAPI void FGAPIENTRY glutWireSphere( GLdouble radius, GLint slices, GLint stacks );
FGAPI void FGAPIENTRY glutSolidSphere( GLdouble radius, GLint slices, GLint stacks );
FGAPI void FGAPIENTRY glutWireCone( GLdouble base, GLdouble height, GLint slices, GLint stacks );
FGAPI void FGAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLint stacks );
FGAPI void FGAPIENTRY glutWireTorus( GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings );
FGAPI void FGAPIENTRY glutSolidTorus( GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings );
FGAPI void FGAPIENTRY glutWireDodecahedron( void );
FGAPI void FGAPIENTRY glutSolidDodecahedron( void );
FGAPI void FGAPIENTRY glutWireOctahedron( void );
FGAPI void FGAPIENTRY glutSolidOctahedron( void );
FGAPI void FGAPIENTRY glutWireTetrahedron( void );
FGAPI void FGAPIENTRY glutSolidTetrahedron( void );
FGAPI void FGAPIENTRY glutWireIcosahedron( void );
FGAPI void FGAPIENTRY glutSolidIcosahedron( void );
/*
* Teapot rendering functions, found in freeglut_teapot.c
*/
FGAPI void FGAPIENTRY glutWireTeapot( GLdouble size );
FGAPI void FGAPIENTRY glutSolidTeapot( GLdouble size );
/*
* Game mode functions, see freeglut_gamemode.c
*/
FGAPI void FGAPIENTRY glutGameModeString( const char* string );
FGAPI int FGAPIENTRY glutEnterGameMode( void );
FGAPI void FGAPIENTRY glutLeaveGameMode( void );
FGAPI int FGAPIENTRY glutGameModeGet( GLenum query );
/*
* Video resize functions, see freeglut_videoresize.c
*/
FGAPI int FGAPIENTRY glutVideoResizeGet( GLenum query );
FGAPI void FGAPIENTRY glutSetupVideoResizing( void );
FGAPI void FGAPIENTRY glutStopVideoResizing( void );
FGAPI void FGAPIENTRY glutVideoResize( int x, int y, int width, int height );
FGAPI void FGAPIENTRY glutVideoPan( int x, int y, int width, int height );
/*
* Colormap functions, see freeglut_misc.c
*/
FGAPI void FGAPIENTRY glutSetColor( int color, GLfloat red, GLfloat green, GLfloat blue );
FGAPI GLfloat FGAPIENTRY glutGetColor( int color, int component );
FGAPI void FGAPIENTRY glutCopyColormap( int window );
/*
* Misc keyboard and joystick functions, see freeglut_misc.c
*/
FGAPI void FGAPIENTRY glutIgnoreKeyRepeat( int ignore );
FGAPI void FGAPIENTRY glutSetKeyRepeat( int repeatMode );
FGAPI void FGAPIENTRY glutForceJoystickFunc( void );
/*
* Misc functions, see freeglut_misc.c
*/
FGAPI int FGAPIENTRY glutExtensionSupported( const char* extension );
FGAPI void FGAPIENTRY glutReportErrors( void );
#ifdef __cplusplus
}
#endif
/*** END OF FILE ***/
#endif /* __FREEGLUT_STD_H__ */

21
Extras/freeglut/GL/glut.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef __GLUT_H__
#define __GLUT_H__
/*
* glut.h
*
* The freeglut library include file
*
* 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.
*/
#include "freeglut_std.h"
/*** END OF FILE ***/
#endif /* __GLUT_H__ */

View File

@ -0,0 +1,361 @@
/*
* freeglut_callbacks.c
*
* The callbacks setting methods.
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Fri Dec 3 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.
*/
#include <GL/freeglut.h>
#include "freeglut_internal.h"
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
/*
* All of the callbacks setting methods can be generalized to this:
*/
#define SET_CALLBACK(a) \
do \
{ \
if( fgStructure.CurrentWindow == NULL ) \
return; \
SET_WCB( ( *( fgStructure.CurrentWindow ) ), a, callback ); \
} while( 0 )
/*
* Sets the Display callback for the current window
*/
void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDisplayFunc" );
if( !callback )
fgError( "Fatal error in program. NULL display callback not "
"permitted in GLUT 3.0+ or freeglut 2.0.1+" );
SET_CALLBACK( Display );
}
/*
* Sets the Reshape callback for the current window
*/
void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReshapeFunc" );
SET_CALLBACK( Reshape );
}
/*
* Sets the Keyboard callback for the current window
*/
void FGAPIENTRY glutKeyboardFunc( void (* callback)
( unsigned char, int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutKeyboardFunc" );
SET_CALLBACK( Keyboard );
}
/*
* Sets the Special callback for the current window
*/
void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpecialFunc" );
SET_CALLBACK( Special );
}
/*
* Sets the global idle callback
*/
void FGAPIENTRY glutIdleFunc( void (* callback)( void ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIdleFunc" );
fgState.IdleCallback = callback;
}
/*
* Sets the Timer callback for the current window
*/
void FGAPIENTRY glutTimerFunc( unsigned int timeOut, void (* callback)( int ),
int timerID )
{
SFG_Timer *timer, *node;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTimerFunc" );
if( (timer = fgState.FreeTimers.Last) )
{
fgListRemove( &fgState.FreeTimers, &timer->Node );
}
else
{
if( ! (timer = malloc(sizeof(SFG_Timer))) )
fgError( "Fatal error: "
"Memory allocation failure in glutTimerFunc()" );
}
timer->Callback = callback;
timer->ID = timerID;
timer->TriggerTime = fgElapsedTime() + timeOut;
for( node = fgState.Timers.First; node; node = node->Node.Next )
{
if( node->TriggerTime > timer->TriggerTime )
break;
}
fgListInsert( &fgState.Timers, &node->Node, &timer->Node );
}
/*
* Sets the Visibility callback for the current window.
*/
static void fghVisibility( int status )
{
int glut_status = GLUT_VISIBLE;
FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Visibility Callback" );
freeglut_return_if_fail( fgStructure.CurrentWindow );
if( ( GLUT_HIDDEN == status ) || ( GLUT_FULLY_COVERED == status ) )
glut_status = GLUT_NOT_VISIBLE;
INVOKE_WCB( *( fgStructure.CurrentWindow ), Visibility, ( glut_status ) );
}
void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutVisibilityFunc" );
SET_CALLBACK( Visibility );
if( callback )
glutWindowStatusFunc( fghVisibility );
else
glutWindowStatusFunc( NULL );
}
/*
* Sets the keyboard key release callback for the current window
*/
void FGAPIENTRY glutKeyboardUpFunc( void (* callback)
( unsigned char, int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutKeyboardUpFunc" );
SET_CALLBACK( KeyboardUp );
}
/*
* Sets the special key release callback for the current window
*/
void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpecialUpFunc" );
SET_CALLBACK( SpecialUp );
}
/*
* Sets the joystick callback and polling rate for the current window
*/
void FGAPIENTRY glutJoystickFunc( void (* callback)
( unsigned int, int, int, int ),
int pollInterval )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutJoystickFunc" );
fgInitialiseJoysticks ();
SET_CALLBACK( Joystick );
fgStructure.CurrentWindow->State.JoystickPollRate = pollInterval;
fgStructure.CurrentWindow->State.JoystickLastPoll =
fgElapsedTime() - fgStructure.CurrentWindow->State.JoystickPollRate;
if( fgStructure.CurrentWindow->State.JoystickLastPoll < 0 )
fgStructure.CurrentWindow->State.JoystickLastPoll = 0;
}
/*
* Sets the mouse callback for the current window
*/
void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMouseFunc" );
SET_CALLBACK( Mouse );
}
/*
* Sets the mouse wheel callback for the current window
*/
void FGAPIENTRY glutMouseWheelFunc( void (* callback)( int, int, int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMouseWheelFunc" );
SET_CALLBACK( MouseWheel );
}
/*
* Sets the mouse motion callback for the current window (one or more buttons
* are pressed)
*/
void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMotionFunc" );
SET_CALLBACK( Motion );
}
/*
* Sets the passive mouse motion callback for the current window (no mouse
* buttons are pressed)
*/
void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPassiveMotionFunc" );
SET_CALLBACK( Passive );
}
/*
* Window mouse entry/leave callback
*/
void FGAPIENTRY glutEntryFunc( void (* callback)( int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutEntryFunc" );
SET_CALLBACK( Entry );
}
/*
* Window destruction callbacks
*/
void FGAPIENTRY glutCloseFunc( void (* callback)( void ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCloseFunc" );
SET_CALLBACK( Destroy );
}
void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWMCloseFunc" );
glutCloseFunc( callback );
}
/* A. Donev: Destruction callback for menus */
void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuDestroyFunc" );
if( fgStructure.CurrentMenu )
fgStructure.CurrentMenu->Destroy = callback;
}
/*
* Deprecated version of glutMenuStatusFunc callback setting method
*/
void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStateFunc" );
fgState.MenuStateCallback = callback;
}
/*
* Sets the global menu status callback for the current window
*/
void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFunc" );
fgState.MenuStatusCallback = callback;
}
/*
* Sets the overlay display callback for the current window
*/
void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutOverlayDisplayFunc" );
SET_CALLBACK( OverlayDisplay );
}
/*
* Sets the window status callback for the current window
*/
void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWindowStatusFunc" );
SET_CALLBACK( WindowStatus );
}
/*
* Sets the spaceball motion callback for the current window
*/
void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballMotionFunc" );
SET_CALLBACK( SpaceMotion );
}
/*
* Sets the spaceball rotate callback for the current window
*/
void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballRotateFunc" );
SET_CALLBACK( SpaceRotation );
}
/*
* Sets the spaceball button callback for the current window
*/
void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballButtonFunc" );
SET_CALLBACK( SpaceButton );
}
/*
* Sets the button box callback for the current window
*/
void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutButtonBoxFunc" );
SET_CALLBACK( ButtonBox );
}
/*
* Sets the dials box callback for the current window
*/
void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDialsFunc" );
SET_CALLBACK( Dials );
}
/*
* Sets the tablet motion callback for the current window
*/
void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTabletMotionFunc" );
SET_CALLBACK( TabletMotion );
}
/*
* Sets the tablet buttons callback for the current window
*/
void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTabletButtonFunc" );
SET_CALLBACK( TabletButton );
}
/*** END OF FILE ***/

View File

@ -0,0 +1,262 @@
/*
* freeglut_cursor.c
*
* The mouse cursor related stuff.
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 16 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.
*/
#include <GL/freeglut.h>
#include "freeglut_internal.h"
#if TARGET_HOST_UNIX_X11
#include <X11/cursorfont.h>
#endif
/*
* TODO BEFORE THE STABLE RELEASE:
* glutSetCursor() -- Win32 mappings are incomplete.
*
* It would be good to use custom mouse cursor shapes, and introduce
* an option to display them using glBitmap() and/or texture mapping,
* apart from the windowing system version.
*/
/* -- PRIVATE FUNCTIONS --------------------------------------------------- */
#if TARGET_HOST_UNIX_X11
/*
* A factory method for an empty cursor
*/
static Cursor getEmptyCursor( void )
{
static Cursor cursorNone = None;
if( cursorNone == None ) {
char cursorNoneBits[ 32 ];
XColor dontCare;
Pixmap cursorNonePixmap;
memset( cursorNoneBits, 0, sizeof( cursorNoneBits ) );
memset( &dontCare, 0, sizeof( dontCare ) );
cursorNonePixmap = XCreateBitmapFromData ( fgDisplay.Display,
fgDisplay.RootWindow,
cursorNoneBits, 16, 16 );
if( cursorNonePixmap != None ) {
cursorNone = XCreatePixmapCursor( fgDisplay.Display,
cursorNonePixmap, cursorNonePixmap,
&dontCare, &dontCare, 0, 0 );
XFreePixmap( fgDisplay.Display, cursorNonePixmap );
}
}
return cursorNone;
}
typedef struct tag_cursorCacheEntry cursorCacheEntry;
struct tag_cursorCacheEntry {
unsigned int cursorShape; /* an XC_foo value */
Cursor cachedCursor; /* None if the corresponding cursor has
not been created yet */
};
/*
* Note: The arrangement of the table below depends on the fact that
* the "normal" GLUT_CURSOR_* values start a 0 and are consecutive.
*/
static cursorCacheEntry cursorCache[] = {
{ XC_arrow, None }, /* GLUT_CURSOR_RIGHT_ARROW */
{ XC_top_left_arrow, None }, /* GLUT_CURSOR_LEFT_ARROW */
{ XC_hand1, None }, /* GLUT_CURSOR_INFO */
{ XC_pirate, None }, /* GLUT_CURSOR_DESTROY */
{ XC_question_arrow, None }, /* GLUT_CURSOR_HELP */
{ XC_exchange, None }, /* GLUT_CURSOR_CYCLE */
{ XC_spraycan, None }, /* GLUT_CURSOR_SPRAY */
{ XC_watch, None }, /* GLUT_CURSOR_WAIT */
{ XC_xterm, None }, /* GLUT_CURSOR_TEXT */
{ XC_crosshair, None }, /* GLUT_CURSOR_CROSSHAIR */
{ XC_sb_v_double_arrow, None }, /* GLUT_CURSOR_UP_DOWN */
{ XC_sb_h_double_arrow, None }, /* GLUT_CURSOR_LEFT_RIGHT */
{ XC_top_side, None }, /* GLUT_CURSOR_TOP_SIDE */
{ XC_bottom_side, None }, /* GLUT_CURSOR_BOTTOM_SIDE */
{ XC_left_side, None }, /* GLUT_CURSOR_LEFT_SIDE */
{ XC_right_side, None }, /* GLUT_CURSOR_RIGHT_SIDE */
{ XC_top_left_corner, None }, /* GLUT_CURSOR_TOP_LEFT_CORNER */
{ XC_top_right_corner, None }, /* GLUT_CURSOR_TOP_RIGHT_CORNER */
{ XC_bottom_right_corner, None }, /* GLUT_CURSOR_BOTTOM_RIGHT_CORNER */
{ XC_bottom_left_corner, None } /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */
};
#endif
/* -- INTERNAL FUNCTIONS ---------------------------------------------------- */
/*
* Set the cursor image to be used for the current window
*/
void fgSetCursor ( SFG_Window *window, int cursorID )
{
#if TARGET_HOST_UNIX_X11
{
Cursor cursor;
/*
* XXX FULL_CROSSHAIR demotes to plain CROSSHAIR. Old GLUT allows
* for this, but if there is a system that easily supports a full-
* window (or full-screen) crosshair, we might consider it.
*/
int cursorIDToUse =
( cursorID == GLUT_CURSOR_FULL_CROSSHAIR ) ? GLUT_CURSOR_CROSSHAIR : cursorID;
if( ( cursorIDToUse >= 0 ) &&
( cursorIDToUse < sizeof( cursorCache ) / sizeof( cursorCache[0] ) ) ) {
cursorCacheEntry *entry = &cursorCache[ cursorIDToUse ];
if( entry->cachedCursor == None ) {
entry->cachedCursor =
XCreateFontCursor( fgDisplay.Display, entry->cursorShape );
}
cursor = entry->cachedCursor;
} else {
switch( cursorIDToUse )
{
case GLUT_CURSOR_NONE:
cursor = getEmptyCursor( );
break;
case GLUT_CURSOR_INHERIT:
cursor = None;
break;
default:
fgError( "Unknown cursor type: %d", cursorIDToUse );
return;
}
}
if ( ( cursorIDToUse != GLUT_CURSOR_NONE ) && ( cursor == None ) ) {
fgError( "Failed to create cursor" );
}
XDefineCursor( fgDisplay.Display,
window->Window.Handle, cursor );
}
#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
/*
* This is a temporary solution only...
*/
/* Set the cursor AND change it for this window class. */
# define MAP_CURSOR(a,b) \
case a: \
SetCursor( LoadCursor( NULL, b ) ); \
SetClassLong( window->Window.Handle, \
GCL_HCURSOR, \
( LONG )LoadCursor( NULL, b ) ); \
break;
/* Nuke the cursor AND change it for this window class. */
# define ZAP_CURSOR(a,b) \
case a: \
SetCursor( NULL ); \
SetClassLong( window->Window.Handle, \
GCL_HCURSOR, ( LONG )NULL ); \
break;
switch( cursorID )
{
MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, IDC_ARROW );
MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW, IDC_ARROW );
MAP_CURSOR( GLUT_CURSOR_INFO, IDC_HELP );
MAP_CURSOR( GLUT_CURSOR_DESTROY, IDC_CROSS );
MAP_CURSOR( GLUT_CURSOR_HELP, IDC_HELP );
MAP_CURSOR( GLUT_CURSOR_CYCLE, IDC_SIZEALL );
MAP_CURSOR( GLUT_CURSOR_SPRAY, IDC_CROSS );
MAP_CURSOR( GLUT_CURSOR_WAIT, IDC_WAIT );
MAP_CURSOR( GLUT_CURSOR_TEXT, IDC_IBEAM );
MAP_CURSOR( GLUT_CURSOR_CROSSHAIR, IDC_CROSS );
MAP_CURSOR( GLUT_CURSOR_UP_DOWN, IDC_SIZENS );
MAP_CURSOR( GLUT_CURSOR_LEFT_RIGHT, IDC_SIZEWE );
MAP_CURSOR( GLUT_CURSOR_TOP_SIDE, IDC_ARROW ); /* XXX ToDo */
MAP_CURSOR( GLUT_CURSOR_BOTTOM_SIDE, IDC_ARROW ); /* XXX ToDo */
MAP_CURSOR( GLUT_CURSOR_LEFT_SIDE, IDC_ARROW ); /* XXX ToDo */
MAP_CURSOR( GLUT_CURSOR_RIGHT_SIDE, IDC_ARROW ); /* XXX ToDo */
MAP_CURSOR( GLUT_CURSOR_TOP_LEFT_CORNER, IDC_SIZENWSE );
MAP_CURSOR( GLUT_CURSOR_TOP_RIGHT_CORNER, IDC_SIZENESW );
MAP_CURSOR( GLUT_CURSOR_BOTTOM_RIGHT_CORNER, IDC_SIZENWSE );
MAP_CURSOR( GLUT_CURSOR_BOTTOM_LEFT_CORNER, IDC_SIZENESW );
MAP_CURSOR( GLUT_CURSOR_INHERIT, IDC_ARROW ); /* XXX ToDo */
ZAP_CURSOR( GLUT_CURSOR_NONE, NULL );
MAP_CURSOR( GLUT_CURSOR_FULL_CROSSHAIR, IDC_CROSS ); /* XXX ToDo */
default:
fgError( "Unknown cursor type: %d", cursorID );
break;
}
#endif
window->State.Cursor = cursorID;
}
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
/*
* Set the cursor image to be used for the current window
*/
void FGAPIENTRY glutSetCursor( int cursorID )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetCursor" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetCursor" );
fgSetCursor ( fgStructure.CurrentWindow, cursorID );
}
/*
* Moves the mouse pointer to given window coordinates
*/
void FGAPIENTRY glutWarpPointer( int x, int y )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWarpPointer" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutWarpPointer" );
#if TARGET_HOST_UNIX_X11
XWarpPointer(
fgDisplay.Display,
None,
fgStructure.CurrentWindow->Window.Handle,
0, 0, 0, 0,
x, y
);
/* Make the warp visible immediately. */
XFlush( fgDisplay.Display );
#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
{
POINT coords;
coords.x = x;
coords.y = y;
/* ClientToScreen() translates {coords} for us. */
ClientToScreen( fgStructure.CurrentWindow->Window.Handle, &coords );
SetCursorPos( coords.x, coords.y );
}
#endif
}
/*** END OF FILE ***/

View File

@ -0,0 +1,94 @@
/*
* freeglut_display.c
*
* Display message posting, context buffer swapping.
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Fri Dec 3 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.
*/
#include <GL/freeglut.h>
#include "freeglut_internal.h"
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
/*
* Marks the current window to have the redisplay performed when possible...
*/
void FGAPIENTRY glutPostRedisplay( void )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPostRedisplay" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutPostRedisplay" );
fgStructure.CurrentWindow->State.Redisplay = GL_TRUE;
}
/*
* Swaps the buffers for the current window (if any)
*/
void FGAPIENTRY glutSwapBuffers( void )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSwapBuffers" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSwapBuffers" );
glFlush( );
if( ! fgStructure.CurrentWindow->Window.DoubleBuffered )
return;
#if TARGET_HOST_UNIX_X11
glXSwapBuffers( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle );
#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
SwapBuffers( fgStructure.CurrentWindow->Window.Device );
#endif
/* GLUT_FPS env var support */
if( fgState.FPSInterval )
{
GLint t = glutGet( GLUT_ELAPSED_TIME );
fgState.SwapCount++;
if( fgState.SwapTime == 0 )
fgState.SwapTime = t;
else if( t - fgState.SwapTime > fgState.FPSInterval )
{
float time = 0.001f * ( t - fgState.SwapTime );
float fps = ( float )fgState.SwapCount / time;
fprintf( stderr,
"freeglut: %d frames in %.2f seconds = %.2f FPS\n",
fgState.SwapCount, time, fps );
fgState.SwapTime = t;
fgState.SwapCount = 0;
}
}
}
/*
* Mark appropriate window to be displayed
*/
void FGAPIENTRY glutPostWindowRedisplay( int windowID )
{
SFG_Window* window;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPostWindowRedisplay" );
window = fgWindowByID( windowID );
freeglut_return_if_fail( window );
window->State.Redisplay = GL_TRUE;
}
/*** END OF FILE ***/

View File

@ -0,0 +1,205 @@
/*
* freeglut_ext.c
*
* Functions related to OpenGL extensions.
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 9 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.
*/
#define GLX_GLXEXT_PROTOTYPES
#include <GL/freeglut.h>
#include "freeglut_internal.h"
static GLUTproc fghGetProcAddress( const char* procName )
{
/* optimization: quick initial b2Assert */
if( strncmp( procName, "glut", 4 ) != 0 )
return NULL;
#define CHECK_NAME(x) if( strcmp( procName, #x ) == 0) return (GLUTproc)x;
CHECK_NAME(glutInit);
CHECK_NAME(glutInitDisplayMode);
CHECK_NAME(glutInitDisplayString);
CHECK_NAME(glutInitWindowPosition);
CHECK_NAME(glutInitWindowSize);
CHECK_NAME(glutMainLoop);
CHECK_NAME(glutCreateWindow);
CHECK_NAME(glutCreateSubWindow);
CHECK_NAME(glutDestroyWindow);
CHECK_NAME(glutPostRedisplay);
CHECK_NAME(glutPostWindowRedisplay);
CHECK_NAME(glutSwapBuffers);
CHECK_NAME(glutGetWindow);
CHECK_NAME(glutSetWindow);
CHECK_NAME(glutSetWindowTitle);
CHECK_NAME(glutSetIconTitle);
CHECK_NAME(glutPositionWindow);
CHECK_NAME(glutReshapeWindow);
CHECK_NAME(glutPopWindow);
CHECK_NAME(glutPushWindow);
CHECK_NAME(glutIconifyWindow);
CHECK_NAME(glutShowWindow);
CHECK_NAME(glutHideWindow);
CHECK_NAME(glutFullScreen);
CHECK_NAME(glutSetCursor);
CHECK_NAME(glutWarpPointer);
CHECK_NAME(glutEstablishOverlay);
CHECK_NAME(glutRemoveOverlay);
CHECK_NAME(glutUseLayer);
CHECK_NAME(glutPostOverlayRedisplay);
CHECK_NAME(glutPostWindowOverlayRedisplay);
CHECK_NAME(glutShowOverlay);
CHECK_NAME(glutHideOverlay);
CHECK_NAME(glutCreateMenu);
CHECK_NAME(glutDestroyMenu);
CHECK_NAME(glutGetMenu);
CHECK_NAME(glutSetMenu);
CHECK_NAME(glutAddMenuEntry);
CHECK_NAME(glutAddSubMenu);
CHECK_NAME(glutChangeToMenuEntry);
CHECK_NAME(glutChangeToSubMenu);
CHECK_NAME(glutRemoveMenuItem);
CHECK_NAME(glutAttachMenu);
CHECK_NAME(glutDetachMenu);
CHECK_NAME(glutDisplayFunc);
CHECK_NAME(glutReshapeFunc);
CHECK_NAME(glutKeyboardFunc);
CHECK_NAME(glutMouseFunc);
CHECK_NAME(glutMotionFunc);
CHECK_NAME(glutPassiveMotionFunc);
CHECK_NAME(glutEntryFunc);
CHECK_NAME(glutVisibilityFunc);
CHECK_NAME(glutIdleFunc);
CHECK_NAME(glutTimerFunc);
CHECK_NAME(glutMenuStateFunc);
CHECK_NAME(glutSpecialFunc);
CHECK_NAME(glutSpaceballMotionFunc);
CHECK_NAME(glutSpaceballRotateFunc);
CHECK_NAME(glutSpaceballButtonFunc);
CHECK_NAME(glutButtonBoxFunc);
CHECK_NAME(glutDialsFunc);
CHECK_NAME(glutTabletMotionFunc);
CHECK_NAME(glutTabletButtonFunc);
CHECK_NAME(glutMenuStatusFunc);
CHECK_NAME(glutOverlayDisplayFunc);
CHECK_NAME(glutWindowStatusFunc);
CHECK_NAME(glutKeyboardUpFunc);
CHECK_NAME(glutSpecialUpFunc);
#if !TARGET_HOST_WINCE
CHECK_NAME(glutJoystickFunc);
#endif /* !TARGET_HOST_WINCE */
CHECK_NAME(glutSetColor);
CHECK_NAME(glutGetColor);
CHECK_NAME(glutCopyColormap);
CHECK_NAME(glutGet);
CHECK_NAME(glutDeviceGet);
CHECK_NAME(glutExtensionSupported);
CHECK_NAME(glutGetModifiers);
CHECK_NAME(glutLayerGet);
CHECK_NAME(glutBitmapCharacter);
CHECK_NAME(glutBitmapWidth);
CHECK_NAME(glutStrokeCharacter);
CHECK_NAME(glutStrokeWidth);
CHECK_NAME(glutBitmapLength);
CHECK_NAME(glutStrokeLength);
CHECK_NAME(glutWireSphere);
CHECK_NAME(glutSolidSphere);
CHECK_NAME(glutWireCone);
CHECK_NAME(glutSolidCone);
CHECK_NAME(glutWireCube);
CHECK_NAME(glutSolidCube);
CHECK_NAME(glutWireTorus);
CHECK_NAME(glutSolidTorus);
CHECK_NAME(glutWireDodecahedron);
CHECK_NAME(glutSolidDodecahedron);
CHECK_NAME(glutWireTeapot);
CHECK_NAME(glutSolidTeapot);
CHECK_NAME(glutWireOctahedron);
CHECK_NAME(glutSolidOctahedron);
CHECK_NAME(glutWireTetrahedron);
CHECK_NAME(glutSolidTetrahedron);
CHECK_NAME(glutWireIcosahedron);
CHECK_NAME(glutSolidIcosahedron);
CHECK_NAME(glutVideoResizeGet);
CHECK_NAME(glutSetupVideoResizing);
CHECK_NAME(glutStopVideoResizing);
CHECK_NAME(glutVideoResize);
CHECK_NAME(glutVideoPan);
CHECK_NAME(glutReportErrors);
CHECK_NAME(glutIgnoreKeyRepeat);
CHECK_NAME(glutSetKeyRepeat);
#if !TARGET_HOST_WINCE
CHECK_NAME(glutForceJoystickFunc);
CHECK_NAME(glutGameModeString);
CHECK_NAME(glutEnterGameMode);
CHECK_NAME(glutLeaveGameMode);
CHECK_NAME(glutGameModeGet);
#endif /* !TARGET_HOST_WINCE */
/* freeglut extensions */
CHECK_NAME(glutMainLoopEvent);
CHECK_NAME(glutLeaveMainLoop);
CHECK_NAME(glutCloseFunc);
CHECK_NAME(glutWMCloseFunc);
CHECK_NAME(glutMenuDestroyFunc);
CHECK_NAME(glutSetOption);
CHECK_NAME(glutSetWindowData);
CHECK_NAME(glutGetWindowData);
CHECK_NAME(glutSetMenuData);
CHECK_NAME(glutGetMenuData);
CHECK_NAME(glutBitmapHeight);
CHECK_NAME(glutStrokeHeight);
CHECK_NAME(glutBitmapString);
CHECK_NAME(glutStrokeString);
CHECK_NAME(glutWireRhombicDodecahedron);
CHECK_NAME(glutSolidRhombicDodecahedron);
CHECK_NAME(glutWireSierpinskiSponge);
CHECK_NAME(glutSolidSierpinskiSponge);
CHECK_NAME(glutWireCylinder);
CHECK_NAME(glutSolidCylinder);
CHECK_NAME(glutGetProcAddress);
CHECK_NAME(glutMouseWheelFunc);
#undef CHECK_NAME
return NULL;
}
GLUTproc FGAPIENTRY
glutGetProcAddress( const char *procName )
{
GLUTproc p;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGetProcAddress" );
/* Try GLUT functions first */
p = fghGetProcAddress( procName );
if( p != NULL )
return p;
/* Try core GL functions */
#if TARGET_HOST_WIN32 || TARGET_HOST_WINCE
return(GLUTproc)wglGetProcAddress( ( LPCSTR )procName );
#elif TARGET_HOST_UNIX_X11 && defined( GLX_ARB_get_proc_address )
return(GLUTproc)glXGetProcAddressARB( ( const GLubyte * )procName );
#else
return NULL;
#endif
}

View File

@ -0,0 +1,380 @@
/*
* freeglut_font.c
*
* Bitmap and stroke fonts displaying.
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 16 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.
*/
#include <GL/freeglut.h>
#include "freeglut_internal.h"
/*
* TODO BEFORE THE STABLE RELEASE:
*
* Test things out ...
*/
/* -- IMPORT DECLARATIONS -------------------------------------------------- */
/*
* These are the font faces defined in freeglut_font_data.c file:
*/
extern SFG_Font fgFontFixed8x13;
extern SFG_Font fgFontFixed9x15;
extern SFG_Font fgFontHelvetica10;
extern SFG_Font fgFontHelvetica12;
extern SFG_Font fgFontHelvetica18;
extern SFG_Font fgFontTimesRoman10;
extern SFG_Font fgFontTimesRoman24;
extern SFG_StrokeFont fgStrokeRoman;
extern SFG_StrokeFont fgStrokeMonoRoman;
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
/*
* Matches a font ID with a SFG_Font structure pointer.
* This was changed to match the GLUT header style.
*/
static SFG_Font* fghFontByID( void* font )
{
if( font == GLUT_BITMAP_8_BY_13 )
return &fgFontFixed8x13;
if( font == GLUT_BITMAP_9_BY_15 )
return &fgFontFixed9x15;
if( font == GLUT_BITMAP_HELVETICA_10 )
return &fgFontHelvetica10;
if( font == GLUT_BITMAP_HELVETICA_12 )
return &fgFontHelvetica12;
if( font == GLUT_BITMAP_HELVETICA_18 )
return &fgFontHelvetica18;
if( font == GLUT_BITMAP_TIMES_ROMAN_10 )
return &fgFontTimesRoman10;
if( font == GLUT_BITMAP_TIMES_ROMAN_24 )
return &fgFontTimesRoman24;
fgWarning( "font 0x%08x not found", font );
return 0;
}
/*
* Matches a font ID with a SFG_StrokeFont structure pointer.
* This was changed to match the GLUT header style.
*/
static SFG_StrokeFont* fghStrokeByID( void* font )
{
if( font == GLUT_STROKE_ROMAN )
return &fgStrokeRoman;
if( font == GLUT_STROKE_MONO_ROMAN )
return &fgStrokeMonoRoman;
fgWarning( "stroke font 0x%08x not found", font );
return 0;
}
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
/*
* Draw a bitmap character
*/
void FGAPIENTRY glutBitmapCharacter( void* fontID, int character )
{
const GLubyte* face;
SFG_Font* font;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapCharacter" );
font = fghFontByID( fontID );
freeglut_return_if_fail( ( character >= 1 )&&( character < 256 ) );
freeglut_return_if_fail( font );
/*
* Find the character we want to draw (???)
*/
face = font->Characters[ character ];
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_FALSE );
glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE );
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glBitmap(
face[ 0 ], font->Height, /* The bitmap's width and height */
font->xorig, font->yorig, /* The origin in the font glyph */
( float )( face[ 0 ] ), 0.0, /* The raster advance -- inc. x,y */
( face + 1 ) /* The packed bitmap data... */
);
glPopClientAttrib( );
}
void FGAPIENTRY glutBitmapString( void* fontID, const unsigned char *string )
{
unsigned char c;
float x = 0.0f ;
SFG_Font* font;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapString" );
font = fghFontByID( fontID );
freeglut_return_if_fail( font );
if ( !string || ! *string )
return;
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_FALSE );
glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE );
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
/*
* Step through the string, drawing each character.
* A newline will simply translate the next character's insertion
* point back to the start of the line and down one line.
*/
while( ( c = *string++) )
if( c == '\n' )
{
glBitmap ( 0, 0, 0, 0, -x, (float) -font->Height, NULL );
x = 0.0f;
}
else /* Not an EOL, draw the bitmap character */
{
const GLubyte* face = font->Characters[ c ];
glBitmap(
face[ 0 ], font->Height, /* Bitmap's width and height */
font->xorig, font->yorig, /* The origin in the font glyph */
( float )( face[ 0 ] ), 0.0, /* The raster advance; inc. x,y */
( face + 1 ) /* The packed bitmap data... */
);
x += ( float )( face[ 0 ] );
}
glPopClientAttrib( );
}
/*
* Returns the width in pixels of a font's character
*/
int FGAPIENTRY glutBitmapWidth( void* fontID, int character )
{
SFG_Font* font;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapWidth" );
font = fghFontByID( fontID );
freeglut_return_val_if_fail( character > 0 && character < 256, 0 );
freeglut_return_val_if_fail( font, 0 );
return *( font->Characters[ character ] );
}
/*
* Return the width of a string drawn using a bitmap font
*/
int FGAPIENTRY glutBitmapLength( void* fontID, const unsigned char* string )
{
unsigned char c;
int length = 0, this_line_length = 0;
SFG_Font* font;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapLength" );
font = fghFontByID( fontID );
freeglut_return_val_if_fail( font, 0 );
if ( !string || ! *string )
return 0;
while( ( c = *string++) )
{
if( c != '\n' )/* Not an EOL, increment length of line */
this_line_length += *( font->Characters[ c ]);
else /* EOL; reset the length of this line */
{
if( length < this_line_length )
length = this_line_length;
this_line_length = 0;
}
}
if ( length < this_line_length )
length = this_line_length;
return length;
}
/*
* Returns the height of a bitmap font
*/
int FGAPIENTRY glutBitmapHeight( void* fontID )
{
SFG_Font* font;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapHeight" );
font = fghFontByID( fontID );
freeglut_return_val_if_fail( font, 0 );
return font->Height;
}
/*
* Draw a stroke character
*/
void FGAPIENTRY glutStrokeCharacter( void* fontID, int character )
{
const SFG_StrokeChar *schar;
const SFG_StrokeStrip *strip;
int i, j;
SFG_StrokeFont* font;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeCharacter" );
font = fghStrokeByID( fontID );
freeglut_return_if_fail( character >= 0 );
freeglut_return_if_fail( character < font->Quantity );
freeglut_return_if_fail( font );
schar = font->Characters[ character ];
freeglut_return_if_fail( schar );
strip = schar->Strips;
for( i = 0; i < schar->Number; i++, strip++ )
{
glBegin( GL_LINE_STRIP );
for( j = 0; j < strip->Number; j++ )
glVertex2f( strip->Vertices[ j ].X, strip->Vertices[ j ].Y );
glEnd( );
}
glTranslatef( schar->Right, 0.0, 0.0 );
}
void FGAPIENTRY glutStrokeString( void* fontID, const unsigned char *string )
{
unsigned char c;
int i, j;
float length = 0.0;
SFG_StrokeFont* font;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeString" );
font = fghStrokeByID( fontID );
freeglut_return_if_fail( font );
if ( !string || ! *string )
return;
/*
* Step through the string, drawing each character.
* A newline will simply translate the next character's insertion
* point back to the start of the line and down one line.
*/
while( ( c = *string++) )
if( c < font->Quantity )
{
if( c == '\n' )
{
glTranslatef ( -length, -( float )( font->Height ), 0.0 );
length = 0.0;
}
else /* Not an EOL, draw the bitmap character */
{
const SFG_StrokeChar *schar = font->Characters[ c ];
if( schar )
{
const SFG_StrokeStrip *strip = schar->Strips;
for( i = 0; i < schar->Number; i++, strip++ )
{
glBegin( GL_LINE_STRIP );
for( j = 0; j < strip->Number; j++ )
glVertex2f( strip->Vertices[ j ].X,
strip->Vertices[ j ].Y);
glEnd( );
}
length += schar->Right;
glTranslatef( schar->Right, 0.0, 0.0 );
}
}
}
}
/*
* Return the width in pixels of a stroke character
*/
int FGAPIENTRY glutStrokeWidth( void* fontID, int character )
{
const SFG_StrokeChar *schar;
SFG_StrokeFont* font;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeWidth" );
font = fghStrokeByID( fontID );
freeglut_return_val_if_fail( ( character >= 0 ) &&
( character < font->Quantity ),
0
);
freeglut_return_val_if_fail( font, 0 );
schar = font->Characters[ character ];
freeglut_return_val_if_fail( schar, 0 );
return ( int )( schar->Right + 0.5 );
}
/*
* Return the width of a string drawn using a stroke font
*/
int FGAPIENTRY glutStrokeLength( void* fontID, const unsigned char* string )
{
unsigned char c;
float length = 0.0;
float this_line_length = 0.0;
SFG_StrokeFont* font;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeLength" );
font = fghStrokeByID( fontID );
freeglut_return_val_if_fail( font, 0 );
if ( !string || ! *string )
return 0;
while( ( c = *string++) )
if( c < font->Quantity )
{
if( c == '\n' ) /* EOL; reset the length of this line */
{
if( length < this_line_length )
length = this_line_length;
this_line_length = 0.0;
}
else /* Not an EOL, increment the length of this line */
{
const SFG_StrokeChar *schar = font->Characters[ c ];
if( schar )
this_line_length += schar->Right;
}
}
if( length < this_line_length )
length = this_line_length;
return( int )( length + 0.5 );
}
/*
* Returns the height of a stroke font
*/
GLfloat FGAPIENTRY glutStrokeHeight( void* fontID )
{
SFG_StrokeFont* font;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeHeight" );
font = fghStrokeByID( fontID );
freeglut_return_val_if_fail( font, 0.0 );
return font->Height;
}
/*** END OF FILE ***/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,597 @@
/*
* freeglut_gamemode.c
*
* The game mode handling code.
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 16 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.
*/
#include <GL/freeglut.h>
#include "freeglut_internal.h"
/*
* TODO BEFORE THE STABLE RELEASE:
*
* glutGameModeString() -- missing
* glutEnterGameMode() -- X11 version
* glutLeaveGameMode() -- is that correct?
* glutGameModeGet() -- is that correct?
*/
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
/*
* Remembers the current visual settings, so that
* we can change them and restore later...
*/
static void fghRememberState( void )
{
#if TARGET_HOST_UNIX_X11
/*
* This highly depends on the XFree86 extensions,
* not approved as X Consortium standards
*/
# ifdef X_XF86VidModeGetModeLine
/*
* Remember the current ViewPort location of the screen to be able to
* restore the ViewPort on LeaveGameMode():
*/
if( !XF86VidModeGetViewPort(
fgDisplay.Display,
fgDisplay.Screen,
&fgDisplay.DisplayViewPortX,
&fgDisplay.DisplayViewPortY ) )
fgWarning( "XF86VidModeGetViewPort failed" );
/*
* Remember the current pointer location before going fullscreen
* for restoring it later:
*/
{
Window junk_window;
unsigned int mask;
XQueryPointer(
fgDisplay.Display, fgDisplay.RootWindow,
&junk_window, &junk_window,
&fgDisplay.DisplayPointerX, &fgDisplay.DisplayPointerY,
&fgDisplay.DisplayPointerX, &fgDisplay.DisplayPointerY, &mask
);
}
/* Query the current display settings: */
fgDisplay.DisplayModeValid =
XF86VidModeGetModeLine(
fgDisplay.Display,
fgDisplay.Screen,
&fgDisplay.DisplayModeClock,
&fgDisplay.DisplayMode
);
if( !fgDisplay.DisplayModeValid )
fgWarning( "XF86VidModeGetModeLine failed" );
# else
/*
* XXX warning fghRememberState: missing XFree86 video mode extensions,
* XXX game mode will not change screen resolution when activated
*/
# endif
#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
/* DEVMODE devMode; */
/* Grab the current desktop settings... */
/* hack to get around my stupid cross-gcc headers */
#define FREEGLUT_ENUM_CURRENT_SETTINGS -1
EnumDisplaySettings( NULL, FREEGLUT_ENUM_CURRENT_SETTINGS,
&fgDisplay.DisplayMode );
/* Make sure we will be restoring all settings needed */
fgDisplay.DisplayMode.dmFields |=
DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
#endif
}
/*
* Restores the previously remembered visual settings
*/
static void fghRestoreState( void )
{
#if TARGET_HOST_UNIX_X11
# ifdef X_XF86VidModeGetAllModeLines
/* Restore the remembered pointer position: */
XWarpPointer(
fgDisplay.Display, None, fgDisplay.RootWindow, 0, 0, 0, 0,
fgDisplay.DisplayPointerX, fgDisplay.DisplayPointerY
);
/*
* This highly depends on the XFree86 extensions,
* not approved as X Consortium standards
*/
if( fgDisplay.DisplayModeValid )
{
XF86VidModeModeInfo** displayModes;
int i, displayModesCount;
if( !XF86VidModeGetAllModeLines(
fgDisplay.Display,
fgDisplay.Screen,
&displayModesCount,
&displayModes ) )
{
fgWarning( "XF86VidModeGetAllModeLines failed" );
return;
}
/*
* Check every of the modes looking for one that matches our demands.
* If we find one, switch to it and restore the remembered viewport.
*/
for( i = 0; i < displayModesCount; i++ )
{
if(displayModes[ i ]->hdisplay == fgDisplay.DisplayMode.hdisplay &&
displayModes[ i ]->vdisplay == fgDisplay.DisplayMode.vdisplay &&
displayModes[ i ]->dotclock == fgDisplay.DisplayModeClock )
{
if( !XF86VidModeSwitchToMode(
fgDisplay.Display,
fgDisplay.Screen,
displayModes[ i ] ) )
{
fgWarning( "XF86VidModeSwitchToMode failed" );
break;
}
if( !XF86VidModeSetViewPort(
fgDisplay.Display,
fgDisplay.Screen,
fgDisplay.DisplayViewPortX,
fgDisplay.DisplayViewPortY ) )
fgWarning( "XF86VidModeSetViewPort failed" );
/*
* For the case this would be the last X11 call the application
* calls exit() we've to flush the X11 output queue to have the
* commands sent to the X server before the application exits.
*/
XFlush( fgDisplay.Display );
break;
}
}
XFree( displayModes );
}
# else
/*
* XXX warning fghRestoreState: missing XFree86 video mode extensions,
* XXX game mode will not change screen resolution when activated
*/
# endif
#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
/* Restore the previously rememebered desktop display settings */
ChangeDisplaySettings( &fgDisplay.DisplayMode, 0 );
#endif
}
#if TARGET_HOST_UNIX_X11
#ifdef X_XF86VidModeGetAllModeLines
/*
* Checks a single display mode settings against user's preferences.
*/
static GLboolean fghCheckDisplayMode( int width, int height, int depth, int refresh )
{
/* The desired values should be stored in fgState structure... */
return ( width == fgState.GameModeSize.X ) &&
( height == fgState.GameModeSize.Y ) &&
( depth == fgState.GameModeDepth ) &&
( refresh == fgState.GameModeRefresh );
}
/*
* Checks all display modes settings against user's preferences.
* Returns the mode number found or -1 if none could be found.
*/
static int fghCheckDisplayModes( GLboolean exactMatch, int displayModesCount, XF86VidModeModeInfo** displayModes )
{
int i;
for( i = 0; i < displayModesCount; i++ )
{
/* Compute the displays refresh rate, dotclock comes in kHz. */
int refresh = ( displayModes[ i ]->dotclock * 1000 ) /
( displayModes[ i ]->htotal * displayModes[ i ]->vtotal );
if( fghCheckDisplayMode( displayModes[ i ]->hdisplay,
displayModes[ i ]->vdisplay,
fgState.GameModeDepth,
( exactMatch ? refresh : fgState.GameModeRefresh ) ) ) {
return i;
}
}
return -1;
}
#endif
#endif
/*
* Changes the current display mode to match user's settings
*/
static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
{
GLboolean success = GL_FALSE;
#if TARGET_HOST_UNIX_X11
/*
* This highly depends on the XFree86 extensions,
* not approved as X Consortium standards
*/
# ifdef X_XF86VidModeGetAllModeLines
/*
* This is also used by applcations which b2Assert modes by calling
* glutGameModeGet(GLUT_GAME_MODE_POSSIBLE), so allow the b2Assert:
*/
if( haveToTest || fgDisplay.DisplayModeValid )
{
XF86VidModeModeInfo** displayModes;
int i, displayModesCount;
if( !XF86VidModeGetAllModeLines(
fgDisplay.Display,
fgDisplay.Screen,
&displayModesCount,
&displayModes ) )
{
fgWarning( "XF86VidModeGetAllModeLines failed" );
return success;
}
/*
* Check every of the modes looking for one that matches our demands,
* ignoring the refresh rate if no exact match could be found.
*/
i = fghCheckDisplayModes( GL_TRUE, displayModesCount, displayModes );
if( i < 0 ) {
i = fghCheckDisplayModes( GL_FALSE, displayModesCount, displayModes );
}
success = ( i < 0 ) ? GL_FALSE : GL_TRUE;
if( !haveToTest && success ) {
if( !XF86VidModeSwitchToMode(
fgDisplay.Display,
fgDisplay.Screen,
displayModes[ i ] ) )
fgWarning( "XF86VidModeSwitchToMode failed" );
}
XFree( displayModes );
}
# else
/*
* XXX warning fghChangeDisplayMode: missing XFree86 video mode extensions,
* XXX game mode will not change screen resolution when activated
*/
success = GL_TRUE;
# endif
#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
DEVMODE devMode;
char *fggmstr = NULL;
success = GL_FALSE;
EnumDisplaySettings( NULL, -1, &devMode );
devMode.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
devMode.dmPelsWidth = fgState.GameModeSize.X;
devMode.dmPelsHeight = fgState.GameModeSize.Y;
devMode.dmBitsPerPel = fgState.GameModeDepth;
devMode.dmDisplayFrequency = fgState.GameModeRefresh;
devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
switch ( ChangeDisplaySettingsEx(NULL, &devMode, NULL, haveToTest ? CDS_TEST : CDS_FULLSCREEN , NULL) )
{
case DISP_CHANGE_SUCCESSFUL:
success = GL_TRUE;
/* update vars in case if windows switched to proper mode */
EnumDisplaySettings( NULL, 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 )
fgWarning(fggmstr); /* 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 ;) */
#endif
return success;
}
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
/*
* Sets the game mode display string
*/
void FGAPIENTRY glutGameModeString( const char* string )
{
int width = 640, height = 480, depth = 16, refresh = 72;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGameModeString" );
/*
* This one seems a bit easier than glutInitDisplayString. The bad thing
* about it that I was unable to find the game mode string definition, so
* that I assumed it is: "[width]x[height]:[depth]@[refresh rate]", which
* appears in all GLUT game mode programs I have seen to date.
*/
if( sscanf( string, "%ix%i:%i@%i", &width, &height, &depth, &refresh ) !=
4 )
if( sscanf( string, "%ix%i:%i", &width, &height, &depth ) != 3 )
if( sscanf( string, "%ix%i@%i", &width, &height, &refresh ) != 3 )
if( sscanf( string, "%ix%i", &width, &height ) != 2 )
if( sscanf( string, ":%i@%i", &depth, &refresh ) != 2 )
if( sscanf( string, ":%i", &depth ) != 1 )
if( sscanf( string, "@%i", &refresh ) != 1 )
fgWarning(
"unable to parse game mode string `%s'",
string
);
/* Hopefully it worked, and if not, we still have the default values */
fgState.GameModeSize.X = width;
fgState.GameModeSize.Y = height;
fgState.GameModeDepth = depth;
fgState.GameModeRefresh = refresh;
}
/*
* Enters the game mode
*/
int FGAPIENTRY glutEnterGameMode( void )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutEnterGameMode" );
if( fgStructure.GameMode )
fgAddToWindowDestroyList( fgStructure.GameMode );
else
fghRememberState( );
if( ! fghChangeDisplayMode( GL_FALSE ) )
{
fgWarning( "failed to change screen settings" );
return 0;
}
fgStructure.GameMode = fgCreateWindow(
NULL, "FREEGLUT", 0, 0,
fgState.GameModeSize.X, fgState.GameModeSize.Y, GL_TRUE, GL_FALSE
);
fgStructure.GameMode->State.Width = fgState.GameModeSize.X;
fgStructure.GameMode->State.Height = fgState.GameModeSize.Y;
fgStructure.GameMode->State.NeedToResize = GL_TRUE;
fgStructure.GameMode->State.IsGameMode = GL_TRUE;
#if TARGET_HOST_UNIX_X11
/*
* Sync needed to avoid a real race, the Xserver must have really created
* the window before we can grab the pointer into it:
*/
XSync( fgDisplay.Display, False );
/*
* Grab the pointer to confine it into the window after the calls to
* XWrapPointer() which ensure that the pointer really enters the window.
*
* We also need to wait here until XGrabPointer() returns GrabSuccess,
* otherwise the new window is not viewable yet and if the next function
* (XSetInputFocus) is called with a not yet viewable window, it will exit
* the application which we have to aviod, so wait until it's viewable:
*/
while( GrabSuccess != XGrabPointer(
fgDisplay.Display, fgStructure.GameMode->Window.Handle,
TRUE,
ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
| PointerMotionMask,
GrabModeAsync, GrabModeAsync,
fgStructure.GameMode->Window.Handle, None, CurrentTime) )
usleep( 100 );
/*
* Change input focus to the new window. This will exit the application
* if the new window is not viewable yet, see the XGrabPointer loop above.
*/
XSetInputFocus(
fgDisplay.Display,
fgStructure.GameMode->Window.Handle,
RevertToNone,
CurrentTime
);
/* Move the Pointer to the middle of the fullscreen window */
XWarpPointer(
fgDisplay.Display,
None,
fgDisplay.RootWindow,
0, 0, 0, 0,
fgState.GameModeSize.X/2, fgState.GameModeSize.Y/2
);
# ifdef X_XF86VidModeSetViewPort
if( fgDisplay.DisplayModeValid )
{
int x, y;
Window child;
/* Change to viewport to the window topleft edge: */
if( !XF86VidModeSetViewPort( fgDisplay.Display, fgDisplay.Screen, 0, 0 ) )
fgWarning( "XF86VidModeSetViewPort failed" );
/*
* Final window repositioning: It could be avoided using an undecorated
* window using override_redirect, but this * would possily require
* more changes and investigation.
*/
/* Get the current postion of the drawable area on screen */
XTranslateCoordinates(
fgDisplay.Display,
fgStructure.CurrentWindow->Window.Handle,
fgDisplay.RootWindow,
0, 0, &x, &y,
&child
);
/* Move the decorataions out of the topleft corner of the display */
XMoveWindow( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle,
-x, -y);
}
#endif
/* Grab the keyboard, too */
XGrabKeyboard(
fgDisplay.Display,
fgStructure.GameMode->Window.Handle,
FALSE,
GrabModeAsync, GrabModeAsync,
CurrentTime
);
#endif
return fgStructure.GameMode->ID;
}
/*
* Leaves the game mode
*/
void FGAPIENTRY glutLeaveGameMode( void )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutLeaveGameMode" );
freeglut_return_if_fail( fgStructure.GameMode );
fgStructure.GameMode->State.IsGameMode = GL_FALSE;
fgAddToWindowDestroyList( fgStructure.GameMode );
fgStructure.GameMode = NULL;
#if TARGET_HOST_UNIX_X11
XUngrabPointer( fgDisplay.Display, CurrentTime );
XUngrabKeyboard( fgDisplay.Display, CurrentTime );
#endif
fghRestoreState();
}
/*
* Returns information concerning the freeglut game mode
*/
int FGAPIENTRY glutGameModeGet( GLenum eWhat )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGameModeGet" );
switch( eWhat )
{
case GLUT_GAME_MODE_ACTIVE:
return !!fgStructure.GameMode;
case GLUT_GAME_MODE_POSSIBLE:
return fghChangeDisplayMode( GL_TRUE );
case GLUT_GAME_MODE_WIDTH:
return fgState.GameModeSize.X;
case GLUT_GAME_MODE_HEIGHT:
return fgState.GameModeSize.Y;
case GLUT_GAME_MODE_PIXEL_DEPTH:
return fgState.GameModeDepth;
case GLUT_GAME_MODE_REFRESH_RATE:
return fgState.GameModeRefresh;
case GLUT_GAME_MODE_DISPLAY_CHANGED:
/*
* This is true if the game mode has been activated successfully..
*/
return !!fgStructure.GameMode;
}
fgWarning( "Unknown gamemode get: %d", eWhat );
return -1;
}
/*** END OF FILE ***/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
/*
* freeglut_glutfont_definitions.c
*
* Bitmap and stroke fonts displaying.
*
* Copyright (c) 2003 Stephen J. Baker (whether he wants it or not).
* All Rights Reserved.
* Written by John F. Fay <fayjf@sourceforge.net>, who releases the
* copyright over to the "freeglut" project lead.
* Creation date: Mon July 21 2003
*
* 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.
*/
/*
* This file is necessary for the *nix version of "freeglut" because the
* original GLUT defined its font variables in rather an unusual way.
* Publicly, in "glut.h", they were defined as "void *". Privately,
* in one of the source code files, they were defined as pointers to a
* structure. Most compilers and linkers are satisfied with the "void *"
* and don't go any farther, but some of them balked. In particular,
* when compiling with "freeglut" and then trying to run using the GLUT
* ".so" library, some of them would give an error. So we are having to
* create this file to define the variables as pointers to an unusual
* structure to match GLUT.
*/
#include "freeglut_internal.h"
#if TARGET_HOST_UNIX_X11
struct freeglutStrokeFont
{
const char *name ;
int num_chars ;
void *ch ;
float top ;
float bottom ;
};
struct freeglutBitmapFont
{
const char *name ;
const int num_chars ;
const int first ;
const void *ch ;
};
struct freeglutStrokeFont glutStrokeRoman ;
struct freeglutStrokeFont glutStrokeMonoRoman ;
struct freeglutBitmapFont glutBitmap9By15 ;
struct freeglutBitmapFont glutBitmap8By13 ;
struct freeglutBitmapFont glutBitmapTimesRoman10 ;
struct freeglutBitmapFont glutBitmapTimesRoman24 ;
struct freeglutBitmapFont glutBitmapHelvetica10 ;
struct freeglutBitmapFont glutBitmapHelvetica12 ;
struct freeglutBitmapFont glutBitmapHelvetica18 ;
#endif

View File

@ -0,0 +1,892 @@
/*
* freeglut_init.c
*
* Various freeglut initialization functions.
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 2 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.
*/
#include <GL/freeglut.h>
#include "freeglut_internal.h"
/*
* TODO BEFORE THE STABLE RELEASE:
*
* fgDeinitialize() -- Win32's OK, X11 needs the OS-specific
* deinitialization done
* glutInitDisplayString() -- display mode string parsing
*
* Wouldn't it be cool to use gettext() for error messages? I just love
* bash saying "nie znaleziono pliku" instead of "file not found" :)
* Is gettext easily portable?
*/
/* -- GLOBAL VARIABLES ----------------------------------------------------- */
/*
* A structure pointed by g_pDisplay holds all information
* regarding the display, screen, root window etc.
*/
SFG_Display fgDisplay;
/*
* The settings for the current freeglut session
*/
SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */
{ 300, 300, GL_TRUE }, /* Size */
GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH, /* DisplayMode */
GL_FALSE, /* Initialised */
GLUT_TRY_DIRECT_CONTEXT, /* DirectContext */
GL_FALSE, /* ForceIconic */
GL_FALSE, /* UseCurrentContext */
GL_FALSE, /* GLDebugSwitch */
GL_FALSE, /* XSyncSwitch */
GLUT_KEY_REPEAT_ON, /* KeyRepeat */
0xffffffff, /* Modifiers */
0, /* FPSInterval */
0, /* SwapCount */
0, /* SwapTime */
#if TARGET_HOST_WIN32 || TARGET_HOST_WINCE
{ 0, GL_FALSE }, /* Time */
#else
{ { 0, 0 }, GL_FALSE },
#endif
{ NULL, NULL }, /* Timers */
{ NULL, NULL }, /* FreeTimers */
NULL, /* IdleCallback */
0, /* ActiveMenus */
NULL, /* MenuStateCallback */
NULL, /* MenuStatusCallback */
{ 640, 480, GL_TRUE }, /* GameModeSize */
16, /* GameModeDepth */
72, /* GameModeRefresh */
GLUT_ACTION_EXIT, /* ActionOnWindowClose */
GLUT_EXEC_STATE_INIT, /* ExecState */
NULL, /* ProgramName */
GL_FALSE /* JoysticksInitialised */
};
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
/*
* A call to this function should initialize all the display stuff...
*/
static void fghInitialize( const char* displayName )
{
#if TARGET_HOST_UNIX_X11
fgDisplay.Display = XOpenDisplay( displayName );
if( fgDisplay.Display == NULL )
fgError( "failed to open display '%s'", XDisplayName( displayName ) );
if( !glXQueryExtension( fgDisplay.Display, NULL, NULL ) )
fgError( "OpenGL GLX extension not supported by display '%s'",
XDisplayName( displayName ) );
fgDisplay.Screen = DefaultScreen( fgDisplay.Display );
fgDisplay.RootWindow = RootWindow(
fgDisplay.Display,
fgDisplay.Screen
);
fgDisplay.ScreenWidth = DisplayWidth(
fgDisplay.Display,
fgDisplay.Screen
);
fgDisplay.ScreenHeight = DisplayHeight(
fgDisplay.Display,
fgDisplay.Screen
);
fgDisplay.ScreenWidthMM = DisplayWidthMM(
fgDisplay.Display,
fgDisplay.Screen
);
fgDisplay.ScreenHeightMM = DisplayHeightMM(
fgDisplay.Display,
fgDisplay.Screen
);
fgDisplay.Connection = ConnectionNumber( fgDisplay.Display );
/* Create the window deletion atom */
fgDisplay.DeleteWindow = XInternAtom(
fgDisplay.Display,
"WM_DELETE_WINDOW",
FALSE
);
#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
WNDCLASS wc;
ATOM atom;
/* What we need to do is to initialize the fgDisplay global structure here. */
fgDisplay.Instance = GetModuleHandle( NULL );
atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc );
if( atom == 0 )
{
ZeroMemory( &wc, sizeof(WNDCLASS) );
/*
* Each of the windows should have its own device context, and we
* want redraw events during Vertical and Horizontal Resizes by
* the user.
*
* XXX Old code had "| CS_DBCLCKS" commented out. Plans for the
* XXX future? Dead-end idea?
*/
wc.lpfnWndProc = fgWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = fgDisplay.Instance;
wc.hIcon = LoadIcon( fgDisplay.Instance, _T("GLUT_ICON") );
#if TARGET_HOST_WIN32
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
if (!wc.hIcon)
wc.hIcon = LoadIcon( NULL, IDI_WINLOGO );
#else /* TARGET_HOST_WINCE */
wc.style = CS_HREDRAW | CS_VREDRAW;
#endif
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = _T("FREEGLUT");
/* Register the window class */
atom = RegisterClass( &wc );
FREEGLUT_INTERNAL_ERROR_EXIT ( atom, "Window Class Not Registered", "fghInitialize" );
}
/* The screen dimensions can be obtained via GetSystemMetrics() calls */
fgDisplay.ScreenWidth = GetSystemMetrics( SM_CXSCREEN );
fgDisplay.ScreenHeight = GetSystemMetrics( SM_CYSCREEN );
{
HWND desktop = GetDesktopWindow( );
HDC context = GetDC( desktop );
fgDisplay.ScreenWidthMM = GetDeviceCaps( context, HORZSIZE );
fgDisplay.ScreenHeightMM = GetDeviceCaps( context, VERTSIZE );
ReleaseDC( desktop, context );
}
/* Set the timer granularity to 1 ms */
timeBeginPeriod ( 1 );
#endif
fgState.Initialised = GL_TRUE;
}
/*
* Perform the freeglut deinitialization...
*/
void fgDeinitialize( void )
{
SFG_Timer *timer;
if( !fgState.Initialised )
{
fgWarning( "fgDeinitialize(): "
"no valid initialization has been performed" );
return;
}
/* If there was a menu created, destroy the rendering context */
if( fgStructure.MenuContext )
{
free( fgStructure.MenuContext );
fgStructure.MenuContext = NULL;
}
fgDestroyStructure( );
while( ( timer = fgState.Timers.First) )
{
fgListRemove( &fgState.Timers, &timer->Node );
free( timer );
}
while( ( timer = fgState.FreeTimers.First) )
{
fgListRemove( &fgState.FreeTimers, &timer->Node );
free( timer );
}
#if !TARGET_HOST_WINCE
if ( fgState.JoysticksInitialised )
fgJoystickClose( );
#endif /* !TARGET_HOST_WINCE */
fgState.JoysticksInitialised = GL_FALSE;
fgState.Initialised = GL_FALSE;
fgState.Position.X = -1;
fgState.Position.Y = -1;
fgState.Position.Use = GL_FALSE;
fgState.Size.X = 300;
fgState.Size.Y = 300;
fgState.Size.Use = GL_TRUE;
fgState.DisplayMode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH;
fgState.DirectContext = GLUT_TRY_DIRECT_CONTEXT;
fgState.ForceIconic = GL_FALSE;
fgState.UseCurrentContext = GL_FALSE;
fgState.GLDebugSwitch = GL_FALSE;
fgState.XSyncSwitch = GL_FALSE;
fgState.ActionOnWindowClose = GLUT_ACTION_EXIT;
fgState.ExecState = GLUT_EXEC_STATE_INIT;
fgState.KeyRepeat = GLUT_KEY_REPEAT_ON;
fgState.Modifiers = 0xffffffff;
fgState.GameModeSize.X = 640;
fgState.GameModeSize.Y = 480;
fgState.GameModeDepth = 16;
fgState.GameModeRefresh = 72;
fgState.Time.Set = GL_FALSE;
fgListInit( &fgState.Timers );
fgListInit( &fgState.FreeTimers );
fgState.IdleCallback = NULL;
fgState.MenuStateCallback = ( FGCBMenuState )NULL;
fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;
fgState.SwapCount = 0;
fgState.SwapTime = 0;
fgState.FPSInterval = 0;
if( fgState.ProgramName )
{
free( fgState.ProgramName );
fgState.ProgramName = NULL;
}
#if TARGET_HOST_UNIX_X11
/*
* Make sure all X-client data we have created will be destroyed on
* display closing
*/
XSetCloseDownMode( fgDisplay.Display, DestroyAll );
/*
* Close the display connection, destroying all windows we have
* created so far
*/
XCloseDisplay( fgDisplay.Display );
#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
/* Reset the timer granularity */
timeEndPeriod ( 1 );
#endif
fgState.Initialised = GL_FALSE;
}
/*
* Everything inside the following #ifndef is copied from the X sources.
*/
#if TARGET_HOST_WIN32 || TARGET_HOST_WINCE
/*
Copyright 1985, 1986, 1987,1998 The Open Group
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
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 THE OPEN GROUP 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.
Except as contained in this notice, the name of The Open Group shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
from The Open Group.
*/
#define NoValue 0x0000
#define XValue 0x0001
#define YValue 0x0002
#define WidthValue 0x0004
#define HeightValue 0x0008
#define AllValues 0x000F
#define XNegative 0x0010
#define YNegative 0x0020
/*
* XParseGeometry parses strings of the form
* "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
* width, height, xoffset, and yoffset are unsigned integers.
* Example: "=80x24+300-49"
* The equal sign is optional.
* It returns a bitmask that indicates which of the four values
* were actually found in the string. For each value found,
* the corresponding argument is updated; for each value
* not found, the corresponding argument is left unchanged.
*/
static int
ReadInteger(char *string, char **NextString)
{
register int Result = 0;
int Sign = 1;
if (*string == '+')
string++;
else if (*string == '-')
{
string++;
Sign = -1;
}
for (; (*string >= '0') && (*string <= '9'); string++)
{
Result = (Result * 10) + (*string - '0');
}
*NextString = string;
if (Sign >= 0)
return Result;
else
return -Result;
}
static int XParseGeometry (
const char *string,
int *x,
int *y,
unsigned int *width, /* RETURN */
unsigned int *height) /* RETURN */
{
int mask = NoValue;
register char *strind;
unsigned int tempWidth = 0, tempHeight = 0;
int tempX = 0, tempY = 0;
char *nextCharacter;
if ( (string == NULL) || (*string == '\0'))
return mask;
if (*string == '=')
string++; /* ignore possible '=' at beg of geometry spec */
strind = (char *)string;
if (*strind != '+' && *strind != '-' && *strind != 'x') {
tempWidth = ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return 0;
strind = nextCharacter;
mask |= WidthValue;
}
if (*strind == 'x' || *strind == 'X') {
strind++;
tempHeight = ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return 0;
strind = nextCharacter;
mask |= HeightValue;
}
if ((*strind == '+') || (*strind == '-')) {
if (*strind == '-') {
strind++;
tempX = -ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return 0;
strind = nextCharacter;
mask |= XNegative;
}
else
{
strind++;
tempX = ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return 0;
strind = nextCharacter;
}
mask |= XValue;
if ((*strind == '+') || (*strind == '-')) {
if (*strind == '-') {
strind++;
tempY = -ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return 0;
strind = nextCharacter;
mask |= YNegative;
}
else
{
strind++;
tempY = ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return 0;
strind = nextCharacter;
}
mask |= YValue;
}
}
/* If strind isn't at the end of the string the it's an invalid
geometry specification. */
if (*strind != '\0') return 0;
if (mask & XValue)
*x = tempX;
if (mask & YValue)
*y = tempY;
if (mask & WidthValue)
*width = tempWidth;
if (mask & HeightValue)
*height = tempHeight;
return mask;
}
#endif
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
/*
* Perform initialization. This usually happens on the program startup
* and restarting after glutMainLoop termination...
*/
void FGAPIENTRY glutInit( int* pargc, char** argv )
{
char* displayName = NULL;
char* geometry = NULL;
int i, j, argc = *pargc;
if( fgState.Initialised )
fgError( "illegal glutInit() reinitialization attempt" );
if (pargc && *pargc && argv && *argv && **argv)
{
fgState.ProgramName = strdup (*argv);
if( !fgState.ProgramName )
fgError ("Could not allocate space for the program's name.");
}
fgCreateStructure( );
fgElapsedTime( );
/* b2Assert if GLUT_FPS env var is set */
#if !TARGET_HOST_WINCE
{
const char *fps = getenv( "GLUT_FPS" );
if( fps )
{
int interval;
sscanf( fps, "%d", &interval );
if( interval <= 0 )
fgState.FPSInterval = 5000; /* 5000 millisecond default */
else
fgState.FPSInterval = interval;
}
}
displayName = getenv( "DISPLAY");
for( i = 1; i < argc; i++ )
{
if( strcmp( argv[ i ], "-display" ) == 0 )
{
if( ++i >= argc )
fgError( "-display parameter must be followed by display name" );
displayName = argv[ i ];
argv[ i - 1 ] = NULL;
argv[ i ] = NULL;
( *pargc ) -= 2;
}
else if( strcmp( argv[ i ], "-geometry" ) == 0 )
{
if( ++i >= argc )
fgError( "-geometry parameter must be followed by window "
"geometry settings" );
geometry = argv[ i ];
argv[ i - 1 ] = NULL;
argv[ i ] = NULL;
( *pargc ) -= 2;
}
else if( strcmp( argv[ i ], "-direct" ) == 0)
{
if( fgState.DirectContext == GLUT_FORCE_INDIRECT_CONTEXT )
fgError( "parameters ambiguity, -direct and -indirect "
"cannot be both specified" );
fgState.DirectContext = GLUT_FORCE_DIRECT_CONTEXT;
argv[ i ] = NULL;
( *pargc )--;
}
else if( strcmp( argv[ i ], "-indirect" ) == 0 )
{
if( fgState.DirectContext == GLUT_FORCE_DIRECT_CONTEXT )
fgError( "parameters ambiguity, -direct and -indirect "
"cannot be both specified" );
fgState.DirectContext = GLUT_FORCE_INDIRECT_CONTEXT;
argv[ i ] = NULL;
(*pargc)--;
}
else if( strcmp( argv[ i ], "-iconic" ) == 0 )
{
fgState.ForceIconic = GL_TRUE;
argv[ i ] = NULL;
( *pargc )--;
}
else if( strcmp( argv[ i ], "-gldebug" ) == 0 )
{
fgState.GLDebugSwitch = GL_TRUE;
argv[ i ] = NULL;
( *pargc )--;
}
else if( strcmp( argv[ i ], "-sync" ) == 0 )
{
fgState.XSyncSwitch = GL_TRUE;
argv[ i ] = NULL;
( *pargc )--;
}
}
/* Compact {argv}. */
for( i = j = 1; i < *pargc; i++, j++ )
{
/* Guaranteed to end because there are "*pargc" arguments left */
while ( argv[ j ] == NULL )
j++;
if ( i != j )
argv[ i ] = argv[ j ];
}
#endif /* TARGET_HOST_WINCE */
/*
* Have the display created now. If there wasn't a "-display"
* in the program arguments, we will use the DISPLAY environment
* variable for opening the X display (see code above):
*/
fghInitialize( displayName );
/*
* Geometry parsing deffered until here because we may need the screen
* size.
*/
if (geometry )
{
unsigned int parsedWidth, parsedHeight;
int mask = XParseGeometry( geometry,
&fgState.Position.X, &fgState.Position.Y,
&parsedWidth, &parsedHeight );
/* TODO: Check for overflow? */
fgState.Size.X = parsedWidth;
fgState.Size.Y = parsedHeight;
if( (mask & (WidthValue|HeightValue)) == (WidthValue|HeightValue) )
fgState.Size.Use = GL_TRUE;
if( mask & XNegative )
fgState.Position.X += fgDisplay.ScreenWidth - fgState.Size.X;
if( mask & YNegative )
fgState.Position.Y += fgDisplay.ScreenHeight - fgState.Size.Y;
if( (mask & (XValue|YValue)) == (XValue|YValue) )
fgState.Position.Use = GL_TRUE;
}
}
/*
* Sets the default initial window position for new windows
*/
void FGAPIENTRY glutInitWindowPosition( int x, int y )
{
fgState.Position.X = x;
fgState.Position.Y = y;
if( ( x >= 0 ) && ( y >= 0 ) )
fgState.Position.Use = GL_TRUE;
else
fgState.Position.Use = GL_FALSE;
}
/*
* Sets the default initial window size for new windows
*/
void FGAPIENTRY glutInitWindowSize( int width, int height )
{
fgState.Size.X = width;
fgState.Size.Y = height;
if( ( width > 0 ) && ( height > 0 ) )
fgState.Size.Use = GL_TRUE;
else
fgState.Size.Use = GL_FALSE;
}
/*
* Sets the default display mode for all new windows
*/
void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode )
{
/* We will make use of this value when creating a new OpenGL context... */
fgState.DisplayMode = displayMode;
}
/* -- INIT DISPLAY STRING PARSING ------------------------------------------ */
static char* Tokens[] =
{
"alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double",
"green", "index", "num", "red", "rgba", "rgb", "luminance", "stencil",
"single", "stereo", "samples", "slow", "win32pdf", "win32pfd", "xvisual",
"xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor",
"xtruecolor", "xdirectcolor",
"xstaticgrey", "xgreyscale", "xstaticcolour", "xpseudocolour",
"xtruecolour", "xdirectcolour", "borderless", "aux"
};
#define NUM_TOKENS (sizeof(Tokens) / sizeof(*Tokens))
void FGAPIENTRY glutInitDisplayString( const char* displayMode )
{
int glut_state_flag = 0 ;
/*
* Unpack a lot of options from a character string. The options are
* delimited by blanks or tabs.
*/
char *token ;
int len = strlen ( displayMode );
char *buffer = (char *)malloc ( (len+1) * sizeof(char) );
memcpy ( buffer, displayMode, len );
buffer[len] = '\0';
token = strtok ( buffer, " \t" );
while ( token )
{
/* Process this token */
int i ;
for ( i = 0; i < NUM_TOKENS; i++ )
{
if ( strcmp ( token, Tokens[i] ) == 0 ) break ;
}
switch ( i )
{
case 0 : /* "alpha": Alpha color buffer precision in bits */
glut_state_flag |= GLUT_ALPHA ; /* Somebody fix this for me! */
break ;
case 1 : /* "acca": Red, green, blue, and alpha accumulation buffer
precision in bits */
break ;
case 2 : /* "acc": Red, green, and blue accumulation buffer precision
in bits with zero bits alpha */
glut_state_flag |= GLUT_ACCUM ; /* Somebody fix this for me! */
break ;
case 3 : /* "blue": Blue color buffer precision in bits */
break ;
case 4 : /* "buffer": Number of bits in the color index color buffer
*/
break ;
case 5 : /* "conformant": Boolean indicating if the frame buffer
configuration is conformant or not */
break ;
case 6 : /* "depth": Number of bits of precsion in the depth buffer */
glut_state_flag |= GLUT_DEPTH ; /* Somebody fix this for me! */
break ;
case 7 : /* "double": Boolean indicating if the color buffer is
double buffered */
glut_state_flag |= GLUT_DOUBLE ;
break ;
case 8 : /* "green": Green color buffer precision in bits */
break ;
case 9 : /* "index": Boolean if the color model is color index or not
*/
glut_state_flag |= GLUT_INDEX ;
break ;
case 10 : /* "num": A special capability name indicating where the
value represents the Nth frame buffer configuration
matching the description string */
break ;
case 11 : /* "red": Red color buffer precision in bits */
break ;
case 12 : /* "rgba": Number of bits of red, green, blue, and alpha in
the RGBA color buffer */
glut_state_flag |= GLUT_RGBA ; /* Somebody fix this for me! */
break ;
case 13 : /* "rgb": Number of bits of red, green, and blue in the
RGBA color buffer with zero bits alpha */
glut_state_flag |= GLUT_RGB ; /* Somebody fix this for me! */
break ;
case 14 : /* "luminance": Number of bits of red in the RGBA and zero
bits of green, blue (alpha not specified) of color buffer
precision */
glut_state_flag |= GLUT_LUMINANCE ; /* Somebody fix this for me! */
break ;
case 15 : /* "stencil": Number of bits in the stencil buffer */
glut_state_flag |= GLUT_STENCIL; /* Somebody fix this for me! */
break ;
case 16 : /* "single": Boolean indicate the color buffer is single
buffered */
glut_state_flag |= GLUT_SINGLE ;
break ;
case 17 : /* "stereo": Boolean indicating the color buffer supports
OpenGL-style stereo */
glut_state_flag |= GLUT_STEREO ;
break ;
case 18 : /* "samples": Indicates the number of multisamples to use
based on GLX's SGIS_multisample extension (for
antialiasing) */
glut_state_flag |= GLUT_MULTISAMPLE ; /*Somebody fix this for me!*/
break ;
case 19 : /* "slow": Boolean indicating if the frame buffer
configuration is slow or not */
break ;
case 20 : /* "win32pdf": (incorrect spelling but was there before */
case 21 : /* "win32pfd": matches the Win32 Pixel Format Descriptor by
number */
#if TARGET_HOST_WIN32
#endif
break ;
case 22 : /* "xvisual": matches the X visual ID by number */
#if TARGET_HOST_UNIX_X11
#endif
break ;
case 23 : /* "xstaticgray": */
case 29 : /* "xstaticgrey": boolean indicating if the frame buffer
configuration's X visual is of type StaticGray */
#if TARGET_HOST_UNIX_X11
#endif
break ;
case 24 : /* "xgrayscale": */
case 30 : /* "xgreyscale": boolean indicating if the frame buffer
configuration's X visual is of type GrayScale */
#if TARGET_HOST_UNIX_X11
#endif
break ;
case 25 : /* "xstaticcolor": */
case 31 : /* "xstaticcolour": boolean indicating if the frame buffer
configuration's X visual is of type StaticColor */
#if TARGET_HOST_UNIX_X11
#endif
break ;
case 26 : /* "xpseudocolor": */
case 32 : /* "xpseudocolour": boolean indicating if the frame buffer
configuration's X visual is of type PseudoColor */
#if TARGET_HOST_UNIX_X11
#endif
break ;
case 27 : /* "xtruecolor": */
case 33 : /* "xtruecolour": boolean indicating if the frame buffer
configuration's X visual is of type TrueColor */
#if TARGET_HOST_UNIX_X11
#endif
break ;
case 28 : /* "xdirectcolor": */
case 34 : /* "xdirectcolour": boolean indicating if the frame buffer
configuration's X visual is of type DirectColor */
#if TARGET_HOST_UNIX_X11
#endif
break ;
case 35 : /* "borderless": windows should not have borders */
#if TARGET_HOST_UNIX_X11
#endif
break ;
case 36 : /* "aux": some number of aux buffers */
glut_state_flag |= GLUT_AUX1;
break ;
case 37 : /* Unrecognized */
fgWarning ( "WARNING - Display string token not recognized: %s",
token );
break ;
}
token = strtok ( NULL, " \t" );
}
free ( buffer );
/* We will make use of this value when creating a new OpenGL context... */
fgState.DisplayMode = glut_state_flag;
}
/*** END OF FILE ***/

View File

@ -0,0 +1,846 @@
/*
* freeglut_internal.h
*
* The freeglut library private include file.
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 2 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.
*/
#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 4
#define VERSION_PATCH 0
/* Freeglut is meant to be available under all Unix/X11 and Win32 platforms. */
#if defined(_WIN32_WCE)
# define TARGET_HOST_UNIX_X11 0
# define TARGET_HOST_WIN32 0
# define TARGET_HOST_WINCE 1
#elif defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__)
# define TARGET_HOST_UNIX_X11 0
# define TARGET_HOST_WIN32 1
# define TARGET_HOST_WINCE 0
#else
# define TARGET_HOST_UNIX_X11 1
# define TARGET_HOST_WIN32 0
# define TARGET_HOST_WINCE 0
#endif
#define FREEGLUT_MAX_MENUS 3
/* Somehow all Win32 include headers depend on this one: */
#if TARGET_HOST_WIN32
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <TCHAR.H>
#endif
#if defined(_MSC_VER)
#define strdup _strdup
#endif
/* Those files should be available on every platform. */
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
/* The system-dependant include files should go here: */
#if TARGET_HOST_UNIX_X11
#include <GL/glx.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
#include <X11/extensions/xf86vmode.h>
#endif
#endif
/* Microsoft VisualC++ 5.0's <math.h> does not define the PI */
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# 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 (* 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
{
void *First;
void *Last;
};
/* A list node structure */
typedef struct tagSFG_Node SFG_Node;
struct tagSFG_Node
{
void *Next;
void *Prev;
};
/* A helper structure holding two ints and a boolean */
typedef struct tagSFG_XYUse SFG_XYUse;
struct tagSFG_XYUse
{
GLint X, Y; /* The two integers... */
GLboolean Use; /* ...and a single boolean. */
};
/* A helper structure holding a timeval and a boolean */
typedef struct tagSFG_Time SFG_Time;
struct tagSFG_Time
{
#if TARGET_HOST_WIN32 || TARGET_HOST_WINCE
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 */
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; /* Display mode for new windows */
GLboolean Initialised; /* freeglut has been initialised */
int DirectContext; /* Direct rendering state */
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 */
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 */
SFG_Time 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 */
int ActiveMenus; /* Num. of currently active menus */
FGCBMenuState MenuStateCallback; /* Menu callbacks are global */
FGCBMenuStatus MenuStatusCallback;
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 closes window */
fgExecutionState ExecState; /* Used for GLUT termination */
char *ProgramName; /* Name of the invoking program */
GLboolean JoysticksInitialised; /* Only initialize if application calls for them */
};
/* The structure used by display initialization in freeglut_init.c */
typedef struct tagSFG_Display SFG_Display;
struct tagSFG_Display
{
#if TARGET_HOST_UNIX_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. */
int Connection; /* The display's connection number */
Atom DeleteWindow; /* The window deletion atom */
#ifdef X_XF86VidModeGetModeLine
/*
* XF86VidMode may be compilable even if it fails at runtime. Therefore,
* the validity of the VidMode has to be tracked
*/
int DisplayModeValid; /* Flag that indicates runtime status*/
XF86VidModeModeLine DisplayMode; /* Current screen's display settings */
int DisplayModeClock; /* The display mode's refresh rate */
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 */
#endif
#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
HINSTANCE Instance; /* The application's instance */
DEVMODE DisplayMode; /* Desktop's display settings */
#endif
int ScreenWidth; /* The screen's width in pixels */
int ScreenHeight; /* The screen's height in pixels */
int ScreenWidthMM; /* The screen's width in milimeters */
int ScreenHeightMM; /* The screen's height in milimeters */
};
/* 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 */
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_UNIX_X11
typedef Window SFG_WindowHandleType ;
typedef GLXContext SFG_WindowContextType ;
#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
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
{
SFG_WindowHandleType Handle; /* The window's handle */
SFG_WindowContextType Context; /* The window's OpenGL/WGL context */
#if TARGET_HOST_UNIX_X11
XVisualInfo* VisualInfo; /* The window's visual information */
#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
HDC Device; /* The window's device context */
#endif
int DoubleBuffered; /* Treat the window as double-buffered */
};
/* 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 */
long JoystickPollRate; /* The joystick polling rate */
long JoystickLastPoll; /* When the last poll happened */
int MouseX, MouseY; /* The most recent mouse position */
GLboolean IgnoreKeyRepeat; /* Whether to ignore key repeat. */
GLboolean KeyRepeating; /* Currently in repeat mode */
GLboolean IsGameMode; /* Is this the game mode window? */
GLboolean NeedToResize; /* Do we need to resize the window? */
};
/*
* 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 void (*SFG_Proc)();
/*
* 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-b2Assert and also sets the
* current window.
*
*/
#if TARGET_HOST_WIN32
#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
XVisualInfo* VisualInfo; /* The window's visual information */
#endif
SFG_WindowContextType Context; /* The menu window's WGL context */
};
/* 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; /* 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 */
struct tagSFG_MenuEntry
{
SFG_Node Node;
int ID; /* The menu entry ID (local) */
int Ordinal; /* The menu's ordinal number */
char* Text; /* The text to be displayed */
SFG_Menu* SubMenu; /* Optional sub-menu tree */
GLboolean IsActive; /* Is the entry highlighted? */
int Width; /* Label's width in pixels */
};
/*
* 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
{
SFG_Node Node;
int ID; /* Window's ID number */
SFG_Context Window; /* Window and OpenGL context */
SFG_WindowState State; /* The window state */
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 */
SFG_Window* Parent; /* The parent to this window */
SFG_List Children; /* The subwindows d.l. list */
GLboolean IsMenu; /* Set to 1 if we are a menu */
};
/* A linked list structure of windows */
typedef struct tagSFG_WindowList SFG_WindowList ;
struct tagSFG_WindowList
{
SFG_Node node;
SFG_Window *window ;
};
/* 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 WindowsToDestroy;
SFG_Window* CurrentWindow; /* The currently set window */
SFG_Menu* CurrentMenu; /* Same, but menu... */
SFG_MenuContext* MenuContext; /* OpenGL rendering context for menus */
SFG_Window* GameMode; /* The game mode window */
int WindowID; /* The new current window ID */
int MenuID; /* The new current menu ID */
};
/*
* This structure is used for the enumeration purposes.
* You can easily extend its functionalities by declaring
* a structure containing enumerator's contents and custom
* data, then casting its pointer to (SFG_Enumerator *).
*/
typedef struct tagSFG_Enumerator SFG_Enumerator;
struct tagSFG_Enumerator
{
GLboolean found; /* Used to terminate search */
void* data; /* Custom data pointer */
};
typedef void (* FGCBenumerator )( SFG_Window *, SFG_Enumerator * );
/* 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 */
float xorig, yorig; /* Relative origin of the character */
};
/* The stroke font structures */
typedef struct tagSFG_StrokeVertex SFG_StrokeVertex;
struct tagSFG_StrokeVertex
{
GLfloat X, Y;
};
typedef struct tagSFG_StrokeStrip SFG_StrokeStrip;
struct tagSFG_StrokeStrip
{
int Number;
const SFG_StrokeVertex* Vertices;
};
typedef struct tagSFG_StrokeChar SFG_StrokeChar;
struct tagSFG_StrokeChar
{
GLfloat Right;
int Number;
const SFG_StrokeStrip* Strips;
};
typedef struct tagSFG_StrokeFont SFG_StrokeFont;
struct tagSFG_StrokeFont
{
char* Name; /* The source font name */
int Quantity; /* Number of chars in font */
GLfloat Height; /* Height of the characters */
const SFG_StrokeChar** Characters; /* The characters mapping */
};
/* -- GLOBAL VARIABLES EXPORTS --------------------------------------------- */
/* Freeglut display related stuff (initialized once per session) */
extern SFG_Display fgDisplay;
/* Freeglut internal structure */
extern SFG_Structure fgStructure;
/* The current freeglut settings */
extern SFG_State fgState;
/* -- PRIVATE FUNCTION DECLARATIONS ---------------------------------------- */
/*
* 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_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 ;
/*
* A call to those macros assures us that there is a current
* window set, respectively:
*/
#define FREEGLUT_EXIT_IF_NO_WINDOW( string ) \
if ( ! fgStructure.CurrentWindow ) \
{ \
fgError ( " ERROR: Function <%s> called" \
" with no current window defined.", (string) ) ; \
}
/*
* The deinitialize function gets called on glutMainLoop() end. It should clean up
* everything inside of the freeglut
*/
void fgDeinitialize( void );
/*
* Those two functions are used to create/destroy the freeglut internal
* structures. This actually happens when calling glutInit() and when
* quitting the glutMainLoop() (which actually happens, when all windows
* have been closed).
*/
void fgCreateStructure( void );
void fgDestroyStructure( void );
/* A helper function to b2Assert if a display mode is possible to use */
#if TARGET_HOST_UNIX_X11
XVisualInfo* fgChooseVisual( void );
#endif
/* The window procedure for Win32 events handling */
#if TARGET_HOST_WIN32 || TARGET_HOST_WINCE
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, GLboolean isMenu );
void fgSetWindow ( SFG_Window *window );
void fgOpenWindow( SFG_Window* window, const char* title,
int x, int y, int w, int h, GLboolean gameMode,
GLboolean isSubWindow );
void fgCloseWindow( SFG_Window* window );
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 );
void fgDestroyMenu( SFG_Menu* menu );
/* Joystick device management functions, defined in freeglut_joystick.c */
int fgJoystickDetect( void );
void fgInitialiseJoysticks( void );
void fgJoystickClose( void );
void fgJoystickPollWindow( SFG_Window* window );
/* More joystick functions. Should these go into the API? */
int glutJoystickGetNumAxes( int ident );
int glutJoystickGetNumButtons( int ident );
int glutJoystickNotWorking( int ident );
/* 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...
*
* The GFunc callback for those functions will be defined as:
*
* void enumCallback( gpointer window, gpointer enumerator );
*
* where window is the enumerated (sub)window pointer (SFG_Window *),
* 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,
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.
*/
SFG_Window* fgWindowByHandle( SFG_WindowHandleType hWindow );
/*
* This function is similiar to the previous one, except it is
* looking for a specified (sub)window identifier. The function
* is defined in freeglut_structure.c file.
*/
SFG_Window* fgWindowByID( int windowID );
/*
* 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 );
/*
* The menu activation and deactivation the code. This is the meat
* of the menu user interface handling code...
*/
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 );
/*
* This function gets called just before the buffers swap, so that
* freeglut can display the pull-down menus via OpenGL. The function
* is defined in freeglut_menu.c file.
*/
void fgDisplayMenu( void );
/* Elapsed time as per glutGet(GLUT_ELAPSED_TIME). */
long fgElapsedTime( 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 Message functions */
void fgError( const char *fmt, ... );
void fgWarning( const char *fmt, ... );
#endif /* FREEGLUT_INTERNAL_H */
/*** 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

@ -0,0 +1,985 @@
/*
* freeglut_menu.c
*
* Pull-down menu creation and handling.
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 16 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.
*/
#include <GL/freeglut.h>
#include "freeglut_internal.h"
/* -- DEFINITIONS ---------------------------------------------------------- */
/*
* FREEGLUT_MENU_FONT can be any freeglut bitmapped font.
* (Stroked fonts would not be out of the question, but we'd need to alter
* code, since GLUT (hence freeglut) does not quite unify stroked and
* bitmapped font handling.)
* Old UNIX/X11 GLUT (BSD, UNIX, IRIX, LINUX, HPUX, ...) used a system
* font best approximated by an 18-pixel HELVETICA, I think. MS-WINDOWS
* GLUT used something closest to the 8x13 fixed-width font. (Old
* GLUT apparently uses host-system menus rather than building its own.
* freeglut is building its own menus from scratch.)
*
* FREEGLUT_MENU_HEIGHT gives the height of ONE menu box. This should be
* the distances between two adjacent menu entries. It should scale
* automatically with the font choice, so you needn't alter it---unless you
* use a stroked font.
*
* FREEGLUT_MENU_BORDER says how many pixels to allow around the edge of a
* menu. (It also seems to be the same as the number of pixels used as
* a border around *items* to separate them from neighbors. John says
* that that wasn't the original intent...if not, perhaps we need another
* symbolic constant, FREEGLUT_MENU_ITEM_BORDER, or such.)
*/
#if TARGET_HOST_WIN32 || TARGET_HOST_WINCE
#define FREEGLUT_MENU_FONT GLUT_BITMAP_8_BY_13
#else
#define FREEGLUT_MENU_FONT GLUT_BITMAP_HELVETICA_18
#endif
#define FREEGLUT_MENU_HEIGHT (glutBitmapHeight(FREEGLUT_MENU_FONT) + \
FREEGLUT_MENU_BORDER)
#define FREEGLUT_MENU_BORDER 2
/*
* These variables are for rendering the freeglut menu items.
*
* The choices are fore- and background, with and without h for Highlighting.
* Old GLUT appeared to be system-dependant for its colors (sigh) so we are
* too. These variables should be stuffed into global state and initialized
* via the glutInit*() system.
*/
#if TARGET_HOST_WIN32 || TARGET_HOST_WINCE
static float menu_pen_fore [4] = {0.0f, 0.0f, 0.0f, 1.0f};
static float menu_pen_back [4] = {0.85f, 0.85f, 0.85f, 1.0f};
static float menu_pen_hfore [4] = {1.0f, 1.0f, 1.0f, 1.0f};
static float menu_pen_hback [4] = {0.15f, 0.15f, 0.45f, 1.0f};
#else
static float menu_pen_fore [4] = {0.0f, 0.0f, 0.0f, 1.0f};
static float menu_pen_back [4] = {0.70f, 0.70f, 0.70f, 1.0f};
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
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
/*
* Private function to find a menu entry by index
*/
static SFG_MenuEntry *fghFindMenuEntry( SFG_Menu* menu, int index )
{
SFG_MenuEntry *entry;
int i = 1;
for( entry = (SFG_MenuEntry *)menu->Entries.First;
entry;
entry = (SFG_MenuEntry *)entry->Node.Next )
{
if( i == index )
break;
++i;
}
return entry;
}
/*
* Deactivates a menu pointed by the function argument.
*/
static void fghDeactivateSubMenu( SFG_MenuEntry *menuEntry )
{
SFG_MenuEntry *subMenuIter;
/* Hide the present menu's window */
fgSetWindow( menuEntry->SubMenu->Window );
glutHideWindow( );
/* Forget about having that menu active anymore, now: */
menuEntry->SubMenu->Window->ActiveMenu = NULL;
menuEntry->SubMenu->IsActive = GL_FALSE;
menuEntry->SubMenu->ActiveEntry = NULL;
/* Hide all submenu windows, and the root menu's window. */
for ( subMenuIter = (SFG_MenuEntry *)menuEntry->SubMenu->Entries.First;
subMenuIter;
subMenuIter = (SFG_MenuEntry *)subMenuIter->Node.Next )
{
subMenuIter->IsActive = GL_FALSE;
/* Is that an active submenu by any case? */
if( subMenuIter->SubMenu )
fghDeactivateSubMenu( subMenuIter );
}
fgSetWindow ( menuEntry->SubMenu->ParentWindow ) ;
}
/*
* Private function to get the virtual maximum screen extent
*/
static GLvoid fghGetVMaxExtent( SFG_Window* window, int* x, int* y )
{
if( fgStructure.GameMode )
{
#if TARGET_HOST_UNIX_X11
int wx, wy;
Window w;
XTranslateCoordinates(
fgDisplay.Display,
window->Window.Handle,
fgDisplay.RootWindow,
0, 0, &wx, &wy, &w);
*x = fgState.GameModeSize.X + wx;
*y = fgState.GameModeSize.Y + wy;
#else
*x = glutGet ( GLUT_SCREEN_WIDTH );
*y = glutGet ( GLUT_SCREEN_HEIGHT );
#endif
}
else
{
*x = fgDisplay.ScreenWidth;
*y = fgDisplay.ScreenHeight;
}
}
/*
* Private function to b2Assert for the current menu/sub menu activity state
*/
static GLboolean fghCheckMenuStatus( SFG_Menu* menu )
{
SFG_MenuEntry* menuEntry;
int x, y;
/* First of all b2Assert any of the active sub menus... */
for( menuEntry = (SFG_MenuEntry *)menu->Entries.First;
menuEntry;
menuEntry = (SFG_MenuEntry *)menuEntry->Node.Next )
{
if( menuEntry->SubMenu && menuEntry->IsActive )
{
/*
* OK, have the sub-menu checked, too. If it returns GL_TRUE, it
* will mean that it caught the mouse cursor and we do not need
* to regenerate the activity list, and so our parents do...
*/
GLboolean return_status;
menuEntry->SubMenu->Window->State.MouseX =
menu->Window->State.MouseX + menu->X - menuEntry->SubMenu->X;
menuEntry->SubMenu->Window->State.MouseY =
menu->Window->State.MouseY + menu->Y - menuEntry->SubMenu->Y;
return_status = fghCheckMenuStatus( menuEntry->SubMenu );
if ( return_status )
return GL_TRUE;
}
}
/* That much about our sub menus, let's get to checking the current menu: */
x = menu->Window->State.MouseX;
y = menu->Window->State.MouseY;
/* Check if the mouse cursor is contained within the current menu box */
if( ( x >= FREEGLUT_MENU_BORDER ) &&
( x < menu->Width - FREEGLUT_MENU_BORDER ) &&
( y >= FREEGLUT_MENU_BORDER ) &&
( y < menu->Height - FREEGLUT_MENU_BORDER ) )
{
int menuID = ( y - FREEGLUT_MENU_BORDER ) / FREEGLUT_MENU_HEIGHT;
/* The mouse cursor is somewhere over our box, b2Assert it out. */
menuEntry = fghFindMenuEntry( menu, menuID + 1 );
FREEGLUT_INTERNAL_ERROR_EXIT( menuEntry, "Cannot find menu entry",
"fghCheckMenuStatus" );
menuEntry->IsActive = GL_TRUE;
menuEntry->Ordinal = menuID;
/*
* If this is not the same as the last active menu entry, deactivate
* the previous entry. Specifically, if the previous active entry
* was a submenu then deactivate it.
*/
if( menu->ActiveEntry && ( menuEntry != menu->ActiveEntry ) )
if( menu->ActiveEntry->SubMenu )
fghDeactivateSubMenu( menu->ActiveEntry );
if( menuEntry != menu->ActiveEntry )
{
menu->Window->State.Redisplay = GL_TRUE;
if( menu->ActiveEntry )
menu->ActiveEntry->IsActive = GL_FALSE;
}
menu->ActiveEntry = menuEntry;
menu->IsActive = GL_TRUE; /* XXX Do we need this? */
/*
* OKi, we have marked that entry as active, but it would be also
* nice to have its contents updated, in case it's a sub menu.
* Also, ignore the return value of the b2Assert function:
*/
if( menuEntry->SubMenu )
{
if ( ! menuEntry->SubMenu->IsActive )
{
int max_x, max_y;
SFG_Window *current_window = fgStructure.CurrentWindow;
/* Set up the initial menu position now... */
menuEntry->SubMenu->IsActive = GL_TRUE;
/* Set up the initial submenu position now: */
fghGetVMaxExtent(menu->ParentWindow, &max_x, &max_y);
menuEntry->SubMenu->X = menu->X + menu->Width;
menuEntry->SubMenu->Y = menu->Y +
menuEntry->Ordinal * FREEGLUT_MENU_HEIGHT;
if( menuEntry->SubMenu->X + menuEntry->SubMenu->Width > max_x )
menuEntry->SubMenu->X = menu->X - menuEntry->SubMenu->Width;
if( menuEntry->SubMenu->Y + menuEntry->SubMenu->Height > max_y )
menuEntry->SubMenu->Y -= ( menuEntry->SubMenu->Height -
FREEGLUT_MENU_HEIGHT -
2 * FREEGLUT_MENU_BORDER );
fgSetWindow( menuEntry->SubMenu->Window );
glutPositionWindow( menuEntry->SubMenu->X,
menuEntry->SubMenu->Y );
glutReshapeWindow( menuEntry->SubMenu->Width,
menuEntry->SubMenu->Height );
glutPopWindow( );
glutShowWindow( );
menuEntry->SubMenu->Window->ActiveMenu = menuEntry->SubMenu;
fgSetWindow( current_window );
menuEntry->SubMenu->Window->State.MouseX =
x + menu->X - menuEntry->SubMenu->X;
menuEntry->SubMenu->Window->State.MouseY =
y + menu->Y - menuEntry->SubMenu->Y;
fghCheckMenuStatus( menuEntry->SubMenu );
}
/* Activate it because its parent entry is active */
menuEntry->SubMenu->IsActive = GL_TRUE; /* XXX Do we need this? */
}
/* Report back that we have caught the menu cursor */
return GL_TRUE;
}
/* Looks like the menu cursor is somewhere else... */
if( menu->ActiveEntry && menu->ActiveEntry->IsActive &&
( !menu->ActiveEntry->SubMenu ||
!menu->ActiveEntry->SubMenu->IsActive ) )
{
menu->Window->State.Redisplay = GL_TRUE;
menu->ActiveEntry->IsActive = GL_FALSE;
menu->ActiveEntry = NULL;
}
return GL_FALSE;
}
/*
* Displays a menu box and all of its submenus (if they are active)
*/
static void fghDisplayMenuBox( SFG_Menu* menu )
{
SFG_MenuEntry *menuEntry;
int i;
int border = FREEGLUT_MENU_BORDER;
/*
* Have the menu box drawn first. The +- values are
* here just to make it more nice-looking...
*/
/* a non-black dark version of the below. */
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glBegin( GL_QUAD_STRIP );
glVertex2i( menu->Width , 0 );
glVertex2i( menu->Width - border, border);
glVertex2i( 0 , 0 );
glVertex2i( border, border);
glVertex2i( 0 , menu->Height );
glVertex2i( border, menu->Height - border);
glEnd( );
/* a non-black dark version of the below. */
glColor4f( 0.5f, 0.5f, 0.5f, 1.0f );
glBegin( GL_QUAD_STRIP );
glVertex2i( 0 , menu->Height );
glVertex2i( border, menu->Height - border);
glVertex2i( menu->Width , menu->Height );
glVertex2i( menu->Width - border, menu->Height - border);
glVertex2i( menu->Width , 0 );
glVertex2i( menu->Width - border, border);
glEnd( );
glColor4fv( menu_pen_back );
glBegin( GL_QUADS );
glVertex2i( border, border);
glVertex2i( menu->Width - border, border);
glVertex2i( menu->Width - border, menu->Height - border);
glVertex2i( border, menu->Height - border);
glEnd( );
/* Check if any of the submenus is currently active... */
for( menuEntry = (SFG_MenuEntry *)menu->Entries.First;
menuEntry;
menuEntry = (SFG_MenuEntry *)menuEntry->Node.Next )
{
/* Has the menu been marked as active, maybe? */
if( menuEntry->IsActive )
{
/*
* That's truly right, and we need to have it highlighted.
* There is an assumption that mouse cursor didn't move
* since the last b2Assert of menu activity state:
*/
int menuID = menuEntry->Ordinal;
/* So have the highlight drawn... */
glColor4fv( menu_pen_hback );
glBegin( GL_QUADS );
glVertex2i( border,
(menuID + 0)*FREEGLUT_MENU_HEIGHT + border );
glVertex2i( menu->Width - border,
(menuID + 0)*FREEGLUT_MENU_HEIGHT + border );
glVertex2i( menu->Width - border,
(menuID + 1)*FREEGLUT_MENU_HEIGHT + border );
glVertex2i( border,
(menuID + 1)*FREEGLUT_MENU_HEIGHT + border );
glEnd( );
}
}
/* Print the menu entries now... */
glColor4fv( menu_pen_fore );
for( menuEntry = (SFG_MenuEntry *)menu->Entries.First, i = 0;
menuEntry;
menuEntry = (SFG_MenuEntry *)menuEntry->Node.Next, ++i )
{
/* If the menu entry is active, set the color to white */
if( menuEntry->IsActive )
glColor4fv( menu_pen_hfore );
/* Move the raster into position... */
/* Try to center the text - JCJ 31 July 2003*/
glRasterPos2i(
2 * border,
( i + 1 )*FREEGLUT_MENU_HEIGHT -
( int )( FREEGLUT_MENU_HEIGHT*0.3 - border )
);
/* Have the label drawn, character after character: */
glutBitmapString( FREEGLUT_MENU_FONT,
(unsigned char *)menuEntry->Text);
/* If it's a submenu, draw a right arrow */
if( menuEntry->SubMenu )
{
int width = glutBitmapWidth( FREEGLUT_MENU_FONT, '_' );
int x_base = menu->Width - 2 - width;
int y_base = i*FREEGLUT_MENU_HEIGHT + border;
glBegin( GL_TRIANGLES );
glVertex2i( x_base, y_base + 2*border);
glVertex2i( menu->Width - 2, y_base +
( FREEGLUT_MENU_HEIGHT + border) / 2 );
glVertex2i( x_base, y_base + FREEGLUT_MENU_HEIGHT - border );
glEnd( );
}
/* If the menu entry is active, reset the color */
if( menuEntry->IsActive )
glColor4fv( menu_pen_fore );
}
}
/*
* Private static function to set the parent window of a submenu and all
* of its submenus
*/
static void fghSetMenuParentWindow( SFG_Window *window, SFG_Menu *menu )
{
SFG_MenuEntry *menuEntry;
menu->ParentWindow = window;
for( menuEntry = ( SFG_MenuEntry * )menu->Entries.First;
menuEntry;
menuEntry = ( SFG_MenuEntry * )menuEntry->Node.Next )
if( menuEntry->SubMenu )
fghSetMenuParentWindow( window, menuEntry->SubMenu );
}
/*
* Function to b2Assert for menu entry selection on menu deactivation
*/
static void fghExecuteMenuCallback( SFG_Menu* menu )
{
SFG_MenuEntry *menuEntry;
/* First of all b2Assert any of the active sub menus... */
for( menuEntry = (SFG_MenuEntry *)menu->Entries.First;
menuEntry;
menuEntry = (SFG_MenuEntry *)menuEntry->Node.Next)
{
if( menuEntry->IsActive )
{
if( menuEntry->SubMenu )
fghExecuteMenuCallback( menuEntry->SubMenu );
else
if( menu->Callback )
{
SFG_Menu *save_menu = fgStructure.CurrentMenu;
fgStructure.CurrentMenu = menu;
menu->Callback( menuEntry->ID );
fgStructure.CurrentMenu = save_menu;
}
return;
}
}
}
/*
* Displays the currently active menu for the current window
*/
void fgDisplayMenu( void )
{
SFG_Window* window = fgStructure.CurrentWindow;
SFG_Menu* menu = NULL;
FREEGLUT_INTERNAL_ERROR_EXIT ( fgStructure.CurrentWindow, "Displaying menu in nonexistent window",
"fgDisplayMenu" );
/* Check if there is an active menu attached to this window... */
menu = window->ActiveMenu;
freeglut_return_if_fail( menu );
fgSetWindow( menu->Window );
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_TEXTURE_BIT | GL_LIGHTING_BIT |
GL_POLYGON_BIT );
glDisable( GL_DEPTH_TEST );
glDisable( GL_TEXTURE_2D );
glDisable( GL_LIGHTING );
glDisable( GL_CULL_FACE );
glMatrixMode( GL_PROJECTION );
glPushMatrix( );
glLoadIdentity( );
glOrtho(
0, glutGet( GLUT_WINDOW_WIDTH ),
glutGet( GLUT_WINDOW_HEIGHT ), 0,
-1, 1
);
glMatrixMode( GL_MODELVIEW );
glPushMatrix( );
glLoadIdentity( );
fghDisplayMenuBox( menu );
glPopAttrib( );
glMatrixMode( GL_PROJECTION );
glPopMatrix( );
glMatrixMode( GL_MODELVIEW );
glPopMatrix( );
glutSwapBuffers( );
fgSetWindow ( window );
}
/*
* Activates a menu pointed by the function argument
*/
static void fghActivateMenu( SFG_Window* window, int button )
{
int max_x, max_y;
/* 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 ( menu->ParentWindow )
menu->ParentWindow->ActiveMenu = NULL ;
/* Mark the menu as active, so that it gets displayed: */
window->ActiveMenu = menu;
menu->IsActive = GL_TRUE;
fghSetMenuParentWindow ( window, menu );
fgState.ActiveMenus++;
/* 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 );
if( menu->X + menu->Width > max_x )
menu->X -=menu->Width;
if( menu->Y + menu->Height > max_y )
menu->Y -=menu->Height;
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;
fgSetWindow( menu->Window );
glutPositionWindow( menu->X, menu->Y );
glutReshapeWindow( menu->Width, menu->Height );
glutPopWindow( );
glutShowWindow( );
menu->Window->ActiveMenu = menu;
fghCheckMenuStatus( menu );
fgSetWindow( current_window );
}
/*
* Update Highlight states of the menu
*
* Current mouse position is in menu->Window->State.MouseX/Y.
*/
void fgUpdateMenuHighlight ( SFG_Menu *menu )
{
fghCheckMenuStatus( menu );
}
/*
* Check whether an active menu absorbs a mouse click
*/
GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed,
int mouse_x, int mouse_y )
{
/*
* Near as I can tell, this is the menu behaviour:
* - Down-click the menu button, menu not active: activate
* the menu with its upper left-hand corner at the mouse
* location.
* - Down-click any button outside the menu, menu active:
* deactivate the menu
* - Down-click any button inside the menu, menu active:
* select the menu entry and deactivate the menu
* - Up-click the menu button, menu not active: nothing happens
* - Up-click the menu button outside the menu, menu active:
* nothing happens
* - Up-click the menu button inside the menu, menu active:
* select the menu entry and deactivate the menu
* Since menus can have submenus, we need to b2Assert this recursively.
*/
if( window->ActiveMenu )
{
if( window == window->ActiveMenu->ParentWindow )
{
window->ActiveMenu->Window->State.MouseX =
mouse_x - window->ActiveMenu->X;
window->ActiveMenu->Window->State.MouseY =
mouse_y - window->ActiveMenu->Y;
}
/* In the menu, invoke the callback and deactivate the menu */
if( fghCheckMenuStatus( window->ActiveMenu ) )
{
/*
* Save the current window and menu and set the current
* window to the window whose menu this is
*/
SFG_Window *save_window = fgStructure.CurrentWindow;
SFG_Menu *save_menu = fgStructure.CurrentMenu;
SFG_Window *parent_window = window->ActiveMenu->ParentWindow;
fgSetWindow( parent_window );
fgStructure.CurrentMenu = window->ActiveMenu;
/* Execute the menu callback */
fghExecuteMenuCallback( window->ActiveMenu );
fgDeactivateMenu( parent_window );
/* Restore the current window and menu */
fgSetWindow( save_window );
fgStructure.CurrentMenu = save_menu;
}
else if( 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.
*/
fgDeactivateMenu( window->ActiveMenu->ParentWindow );
/*
* XXX Why does an active menu require a redisplay at
* XXX this point? If this can come out cleanly, then
* XXX it probably should do so; if not, a comment should
* XXX explain it.
*/
if( ! window->IsMenu )
window->State.Redisplay = GL_TRUE;
return GL_TRUE;
}
/* No active menu, let's b2Assert whether we need to activate one. */
if( ( 0 <= button ) &&
( FREEGLUT_MAX_MENUS > button ) &&
( window->Menu[ button ] ) &&
pressed )
{
/* XXX Posting a requisite Redisplay seems bogus. */
window->State.Redisplay = GL_TRUE;
fghActivateMenu( window, button );
return GL_TRUE;
}
return GL_FALSE;
}
/*
* Deactivates a menu pointed by the function argument.
*/
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_MenuEntry *menuEntry;
/* Did we find an active window? */
freeglut_return_if_fail( menu );
parent_window = menu->ParentWindow;
/* Hide the present menu's window */
fgSetWindow( menu->Window );
glutHideWindow( );
/* Forget about having that menu active anymore, now: */
menu->Window->ActiveMenu = NULL;
menu->ParentWindow->ActiveMenu = NULL;
fghSetMenuParentWindow ( NULL, menu );
menu->IsActive = GL_FALSE;
menu->ActiveEntry = NULL;
fgState.ActiveMenus--;
/* Hide all submenu windows, and the root menu's window. */
for ( menuEntry = ( SFG_MenuEntry * )menu->Entries.First;
menuEntry;
menuEntry = ( SFG_MenuEntry * )menuEntry->Node.Next )
{
menuEntry->IsActive = GL_FALSE;
/* Is that an active submenu by any case? */
if( menuEntry->SubMenu )
fghDeactivateSubMenu( menuEntry );
}
fgSetWindow ( parent_window ) ;
}
/*
* Recalculates current menu's box size
*/
void fghCalculateMenuBoxSize( void )
{
SFG_MenuEntry* menuEntry;
int width = 0, height = 0;
/* Make sure there is a current menu set */
freeglut_return_if_fail( fgStructure.CurrentMenu );
/* The menu's box size depends on the menu entries: */
for( menuEntry = ( SFG_MenuEntry * )fgStructure.CurrentMenu->Entries.First;
menuEntry;
menuEntry = ( SFG_MenuEntry * )menuEntry->Node.Next )
{
/* Update the menu entry's width value */
menuEntry->Width = glutBitmapLength(
FREEGLUT_MENU_FONT,
(unsigned char *)menuEntry->Text
);
/*
* If the entry is a submenu, then it needs to be wider to
* accomodate the arrow. JCJ 31 July 2003
*/
if (menuEntry->SubMenu )
menuEntry->Width += glutBitmapLength(
FREEGLUT_MENU_FONT,
(unsigned char *)"_"
);
/* Check if it's the biggest we've found */
if( menuEntry->Width > width )
width = menuEntry->Width;
height += FREEGLUT_MENU_HEIGHT;
}
/* Store the menu's box size now: */
fgStructure.CurrentMenu->Height = height + 2 * FREEGLUT_MENU_BORDER;
fgStructure.CurrentMenu->Width = width + 4 * FREEGLUT_MENU_BORDER;
}
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
/*
* Creates a new menu object, adding it to the freeglut structure
*/
int FGAPIENTRY glutCreateMenu( void(* callback)( int ) )
{
/* The menu object creation code resides in freeglut_structure.c */
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCreateMenu" );
return fgCreateMenu( callback )->ID;
}
/*
* Destroys a menu object, removing all references to it
*/
void FGAPIENTRY glutDestroyMenu( int menuID )
{
SFG_Menu* menu;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDestroyMenu" );
menu = fgMenuByID( menuID );
freeglut_return_if_fail( menu );
/* The menu object destruction code resides in freeglut_structure.c */
fgDestroyMenu( menu );
}
/*
* Returns the ID number of the currently active menu
*/
int FGAPIENTRY glutGetMenu( void )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGetMenu" );
if( fgStructure.CurrentMenu )
return fgStructure.CurrentMenu->ID;
return 0;
}
/*
* Sets the current menu given its menu ID
*/
void FGAPIENTRY glutSetMenu( int menuID )
{
SFG_Menu* menu;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetMenu" );
menu = fgMenuByID( menuID );
freeglut_return_if_fail( menu );
fgStructure.CurrentMenu = menu;
}
/*
* Adds a menu entry to the bottom of the current menu
*/
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 );
menuEntry->Text = strdup( label );
menuEntry->ID = value;
/* Have the new menu entry attached to the current menu */
fgListAppend( &fgStructure.CurrentMenu->Entries, &menuEntry->Node );
fghCalculateMenuBoxSize( );
}
/*
* Add a sub menu to the bottom of the current menu
*/
void FGAPIENTRY glutAddSubMenu( const char *label, int subMenuID )
{
SFG_MenuEntry *menuEntry;
SFG_Menu *subMenu;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutAddSubMenu" );
menuEntry = ( SFG_MenuEntry * )calloc( sizeof( SFG_MenuEntry ), 1 );
subMenu = fgMenuByID( subMenuID );
freeglut_return_if_fail( fgStructure.CurrentMenu );
freeglut_return_if_fail( subMenu );
menuEntry->Text = strdup( label );
menuEntry->SubMenu = subMenu;
menuEntry->ID = -1;
fgListAppend( &fgStructure.CurrentMenu->Entries, &menuEntry->Node );
fghCalculateMenuBoxSize( );
}
/*
* Changes the specified menu item in the current menu into a menu entry
*/
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 );
/* Get n-th menu entry in the current menu, starting from one: */
menuEntry = fghFindMenuEntry( fgStructure.CurrentMenu, item );
freeglut_return_if_fail( menuEntry );
/* We want it to become a normal menu entry, so: */
if( menuEntry->Text )
free( menuEntry->Text );
menuEntry->Text = strdup( label );
menuEntry->ID = value;
menuEntry->SubMenu = NULL;
fghCalculateMenuBoxSize( );
}
/*
* Changes the specified menu item in the current menu into a sub-menu trigger.
*/
void FGAPIENTRY glutChangeToSubMenu( int item, const char* label,
int subMenuID )
{
SFG_Menu* subMenu;
SFG_MenuEntry* menuEntry;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutChangeToSubMenu" );
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: */
menuEntry = fghFindMenuEntry( fgStructure.CurrentMenu, item );
freeglut_return_if_fail( menuEntry );
/* We want it to become a sub menu entry, so: */
if( menuEntry->Text )
free( menuEntry->Text );
menuEntry->Text = strdup( label );
menuEntry->SubMenu = subMenu;
menuEntry->ID = -1;
fghCalculateMenuBoxSize( );
}
/*
* Removes the specified menu item from the current menu
*/
void FGAPIENTRY glutRemoveMenuItem( int item )
{
SFG_MenuEntry* menuEntry;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutRemoveMenuItem" );
freeglut_return_if_fail( fgStructure.CurrentMenu );
/* Get n-th menu entry in the current menu, starting from one: */
menuEntry = fghFindMenuEntry( fgStructure.CurrentMenu, item );
freeglut_return_if_fail( menuEntry );
fgListRemove( &fgStructure.CurrentMenu->Entries, &menuEntry->Node );
if ( menuEntry->Text )
free( menuEntry->Text );
free( menuEntry );
fghCalculateMenuBoxSize( );
}
/*
* Attaches a menu to the current window
*/
void FGAPIENTRY glutAttachMenu( int button )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutAttachMenu" );
freeglut_return_if_fail( fgStructure.CurrentWindow );
freeglut_return_if_fail( fgStructure.CurrentMenu );
freeglut_return_if_fail( button >= 0 );
freeglut_return_if_fail( button < FREEGLUT_MAX_MENUS );
fgStructure.CurrentWindow->Menu[ button ] = fgStructure.CurrentMenu;
}
/*
* Detaches a menu from the current window
*/
void FGAPIENTRY glutDetachMenu( int button )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDetachMenu" );
freeglut_return_if_fail( fgStructure.CurrentWindow );
freeglut_return_if_fail( fgStructure.CurrentMenu );
freeglut_return_if_fail( button >= 0 );
freeglut_return_if_fail( button < FREEGLUT_MAX_MENUS );
fgStructure.CurrentWindow->Menu[ button ] = NULL;
}
/*
* A.Donev: Set and retrieve the menu's user data
*/
void* FGAPIENTRY glutGetMenuData( void )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGetMenuData" );
return fgStructure.CurrentMenu->UserData;
}
void FGAPIENTRY glutSetMenuData(void* data)
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetMenuData" );
fgStructure.CurrentMenu->UserData=data;
}
/*** END OF FILE ***/

View File

@ -0,0 +1,171 @@
/*
* freeglut_misc.c
*
* Functions that didn't fit anywhere else...
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 9 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.
*/
#include <GL/freeglut.h>
#include "freeglut_internal.h"
/*
* TODO BEFORE THE STABLE RELEASE:
*
* glutSetColor() --
* glutGetColor() --
* glutCopyColormap() --
* glutSetKeyRepeat() -- this is evil and should be removed from API
*/
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
/*
* This functions checks if an OpenGL extension is supported or not
*
* XXX Wouldn't this be simpler and clearer if we used strtok()?
*/
int FGAPIENTRY glutExtensionSupported( const char* extension )
{
const char *extensions, *start;
const int len = strlen( extension );
/* Make sure there is a current window, and thus a current context available */
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutExtensionSupported" );
freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 );
if (strchr(extension, ' '))
return 0;
start = extensions = (const char *) glGetString(GL_EXTENSIONS);
/* XXX consider printing a warning to stderr that there's no current
* rendering context.
*/
freeglut_return_val_if_fail( extensions != NULL, 0 );
while (1) {
const char *p = strstr(extensions, extension);
if (!p)
return 0; /* not found */
/* b2Assert that the match isn't a super string */
if ((p == start || p[-1] == ' ') && (p[len] == ' ' || p[len] == 0))
return 1;
/* skip the false match and continue */
extensions = p + len;
}
return 0 ;
}
/*
* This function reports all the OpenGL errors that happened till now
*/
void FGAPIENTRY glutReportErrors( void )
{
GLenum error;
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReportErrors" );
while( ( error = glGetError() ) != GL_NO_ERROR )
fgWarning( "GL error: %s", gluErrorString( error ) );
}
/*
* Control the auto-repeat of keystrokes to the current window
*/
void FGAPIENTRY glutIgnoreKeyRepeat( int ignore )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIgnoreKeyRepeat" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutIgnoreKeyRepeat" );
fgStructure.CurrentWindow->State.IgnoreKeyRepeat = ignore ? GL_TRUE : GL_FALSE;
}
/*
* Set global auto-repeat of keystrokes
*
* RepeatMode should be either:
* GLUT_KEY_REPEAT_OFF
* GLUT_KEY_REPEAT_ON
* GLUT_KEY_REPEAT_DEFAULT
*/
void FGAPIENTRY glutSetKeyRepeat( int repeatMode )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetKeyRepeat" );
switch( repeatMode )
{
case GLUT_KEY_REPEAT_OFF:
case GLUT_KEY_REPEAT_ON:
fgState.KeyRepeat = repeatMode;
break;
case GLUT_KEY_REPEAT_DEFAULT:
fgState.KeyRepeat = GLUT_KEY_REPEAT_ON;
break;
default:
fgError ("Invalid glutSetKeyRepeat mode: %d", repeatMode);
break;
}
}
/*
* Forces the joystick callback to be executed
*/
void FGAPIENTRY glutForceJoystickFunc( void )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutForceJoystickFunc" );
#if !TARGET_HOST_WINCE
freeglut_return_if_fail( fgStructure.CurrentWindow != NULL );
freeglut_return_if_fail( FETCH_WCB( *( fgStructure.CurrentWindow ), Joystick ) );
fgJoystickPollWindow( fgStructure.CurrentWindow );
#endif /* !TARGET_HOST_WINCE */
}
/*
*
*/
void FGAPIENTRY glutSetColor( int nColor, GLfloat red, GLfloat green, GLfloat blue )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetColor" );
/* We really need to do something here. */
}
/*
*
*/
GLfloat FGAPIENTRY glutGetColor( int color, int component )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGetColor" );
/* We really need to do something here. */
return( 0.0f );
}
/*
*
*/
void FGAPIENTRY glutCopyColormap( int window )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCopyColormap" );
/* We really need to do something here. */
}
/*** END OF FILE ***/

View File

@ -0,0 +1,45 @@
/*
* freeglut_overlay.c
*
* Overlay management functions (as defined by GLUT API)
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 16 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.
*/
#include <GL/freeglut.h>
#include "freeglut_internal.h"
/*
* NOTE: functions declared in this file probably will not be implemented.
*/
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
void FGAPIENTRY glutEstablishOverlay( void ) { /* Not implemented */ }
void FGAPIENTRY glutRemoveOverlay( void ) { /* Not implemented */ }
void FGAPIENTRY glutUseLayer( GLenum layer ) { /* Not implemented */ }
void FGAPIENTRY glutPostOverlayRedisplay( void ) { /* Not implemented */ }
void FGAPIENTRY glutPostWindowOverlayRedisplay( int ID ) { /* Not implemented */ }
void FGAPIENTRY glutShowOverlay( void ) { /* Not implemented */ }
void FGAPIENTRY glutHideOverlay( void ) { /* Not implemented */ }
/*** END OF FILE ***/

View File

@ -0,0 +1,664 @@
/*
* freeglut_state.c
*
* Freeglut state query methods.
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 16 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.
*/
#include <GL/freeglut.h>
#include "freeglut_internal.h"
/*
* TODO BEFORE THE STABLE RELEASE:
*
* glutGet() -- X11 tests passed, but b2Assert if all enums
* handled (what about Win32?)
* glutDeviceGet() -- X11 tests passed, but b2Assert if all enums
* handled (what about Win32?)
* glutGetModifiers() -- OK, but could also remove the limitation
* glutLayerGet() -- what about GLUT_NORMAL_DAMAGED?
*
* The fail-on-call policy will help adding the most needed things imho.
*/
/* -- LOCAL DEFINITIONS ---------------------------------------------------- */
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
#if TARGET_HOST_UNIX_X11
/*
* Queries the GL context about some attributes
*/
static int fghGetConfig( int attribute )
{
int returnValue = 0;
if( fgStructure.CurrentWindow )
glXGetConfig( fgDisplay.Display, fgStructure.CurrentWindow->Window.VisualInfo,
attribute, &returnValue );
return returnValue;
}
#endif
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
/*
* General settings assignment method
*/
void FGAPIENTRY glutSetOption( GLenum eWhat, int value )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetOption" );
/*
* XXX In chronological code add order. (WHY in that order?)
*/
switch( eWhat )
{
case GLUT_INIT_WINDOW_X:
fgState.Position.X = (GLint)value;
break;
case GLUT_INIT_WINDOW_Y:
fgState.Position.Y = (GLint)value;
break;
case GLUT_INIT_WINDOW_WIDTH:
fgState.Size.X = (GLint)value;
break;
case GLUT_INIT_WINDOW_HEIGHT:
fgState.Size.Y = (GLint)value;
break;
case GLUT_INIT_DISPLAY_MODE:
fgState.DisplayMode = (unsigned int)value;
break;
case GLUT_ACTION_ON_WINDOW_CLOSE:
fgState.ActionOnWindowClose = value;
break;
case GLUT_RENDERING_CONTEXT:
fgState.UseCurrentContext =
( value == GLUT_USE_CURRENT_CONTEXT ) ? GL_TRUE : GL_FALSE;
break;
case GLUT_DIRECT_RENDERING:
fgState.DirectContext = value;
break;
case GLUT_WINDOW_CURSOR:
if( fgStructure.CurrentWindow != NULL )
fgStructure.CurrentWindow->State.Cursor = value;
break;
default:
fgWarning( "glutSetOption(): missing enum handle %d", eWhat );
break;
}
}
/*
* General settings query method
*/
int FGAPIENTRY glutGet( GLenum eWhat )
{
#if TARGET_HOST_WIN32 || TARGET_HOST_WINCE
int returnValue ;
GLboolean boolValue ;
#endif
switch (eWhat)
{
case GLUT_INIT_STATE:
return fgState.Initialised;
case GLUT_ELAPSED_TIME:
return fgElapsedTime();
}
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGet" );
/* XXX In chronological code add order. (WHY in that order?) */
switch( eWhat )
{
/* Following values are stored in fgState and fgDisplay global structures */
case GLUT_SCREEN_WIDTH: return fgDisplay.ScreenWidth ;
case GLUT_SCREEN_HEIGHT: return fgDisplay.ScreenHeight ;
case GLUT_SCREEN_WIDTH_MM: return fgDisplay.ScreenWidthMM ;
case GLUT_SCREEN_HEIGHT_MM: return fgDisplay.ScreenHeightMM;
case GLUT_INIT_WINDOW_X: return fgState.Position.X ;
case GLUT_INIT_WINDOW_Y: return fgState.Position.Y ;
case GLUT_INIT_WINDOW_WIDTH: return fgState.Size.X ;
case GLUT_INIT_WINDOW_HEIGHT: return fgState.Size.Y ;
case GLUT_INIT_DISPLAY_MODE: return fgState.DisplayMode ;
/*
* The window/context specific queries are handled mostly by
* fghGetConfig().
*/
case GLUT_WINDOW_NUM_SAMPLES:
/* XXX Multisampling. Return what I know about multisampling. */
return 0;
#if TARGET_HOST_UNIX_X11
/*
* The rest of GLX queries under X are general enough to use a macro to
* b2Assert them
*/
# define GLX_QUERY(a,b) case a: return fghGetConfig( b );
GLX_QUERY( GLUT_WINDOW_RGBA, GLX_RGBA );
GLX_QUERY( GLUT_WINDOW_DOUBLEBUFFER, GLX_DOUBLEBUFFER );
GLX_QUERY( GLUT_WINDOW_BUFFER_SIZE, GLX_BUFFER_SIZE );
GLX_QUERY( GLUT_WINDOW_STENCIL_SIZE, GLX_STENCIL_SIZE );
GLX_QUERY( GLUT_WINDOW_DEPTH_SIZE, GLX_DEPTH_SIZE );
GLX_QUERY( GLUT_WINDOW_RED_SIZE, GLX_RED_SIZE );
GLX_QUERY( GLUT_WINDOW_GREEN_SIZE, GLX_GREEN_SIZE );
GLX_QUERY( GLUT_WINDOW_BLUE_SIZE, GLX_BLUE_SIZE );
GLX_QUERY( GLUT_WINDOW_ALPHA_SIZE, GLX_ALPHA_SIZE );
GLX_QUERY( GLUT_WINDOW_ACCUM_RED_SIZE, GLX_ACCUM_RED_SIZE );
GLX_QUERY( GLUT_WINDOW_ACCUM_GREEN_SIZE, GLX_ACCUM_GREEN_SIZE );
GLX_QUERY( GLUT_WINDOW_ACCUM_BLUE_SIZE, GLX_ACCUM_BLUE_SIZE );
GLX_QUERY( GLUT_WINDOW_ACCUM_ALPHA_SIZE, GLX_ACCUM_ALPHA_SIZE );
GLX_QUERY( GLUT_WINDOW_STEREO, GLX_STEREO );
# undef GLX_QUERY
/* Colormap size is handled in a bit different way than all the rest */
case GLUT_WINDOW_COLORMAP_SIZE:
if( (fghGetConfig( GLX_RGBA )) || (fgStructure.CurrentWindow == NULL) )
{
/*
* We've got a RGBA visual, so there is no colormap at all.
* The other possibility is that we have no current window set.
*/
return 0;
}
return fgStructure.CurrentWindow->Window.VisualInfo->visual->map_entries;
/*
* Those calls are somewhat similiar, as they use XGetWindowAttributes()
* function
*/
case GLUT_WINDOW_X:
case GLUT_WINDOW_Y:
case GLUT_WINDOW_BORDER_WIDTH:
case GLUT_WINDOW_HEADER_HEIGHT:
{
int x, y;
Window w;
if( fgStructure.CurrentWindow == NULL )
return 0;
XTranslateCoordinates(
fgDisplay.Display,
fgStructure.CurrentWindow->Window.Handle,
fgDisplay.RootWindow,
0, 0, &x, &y, &w);
switch ( eWhat )
{
case GLUT_WINDOW_X: return x;
case GLUT_WINDOW_Y: return y;
}
if ( w == 0 )
return 0;
XTranslateCoordinates(
fgDisplay.Display,
fgStructure.CurrentWindow->Window.Handle,
w, 0, 0, &x, &y, &w);
switch ( eWhat )
{
case GLUT_WINDOW_BORDER_WIDTH: return x;
case GLUT_WINDOW_HEADER_HEIGHT: return y;
}
}
case GLUT_WINDOW_WIDTH:
case GLUT_WINDOW_HEIGHT:
{
XWindowAttributes winAttributes;
if( fgStructure.CurrentWindow == NULL )
return 0;
XGetWindowAttributes(
fgDisplay.Display,
fgStructure.CurrentWindow->Window.Handle,
&winAttributes
);
switch ( eWhat )
{
case GLUT_WINDOW_WIDTH: return winAttributes.width ;
case GLUT_WINDOW_HEIGHT: return winAttributes.height ;
}
}
/* I do not know yet if there will be a fgChooseVisual() function for Win32 */
case GLUT_DISPLAY_MODE_POSSIBLE:
return( fgChooseVisual() == NULL ? 0 : 1 );
/* This is system-dependant */
case GLUT_WINDOW_FORMAT_ID:
if( fgStructure.CurrentWindow == NULL )
return 0;
return fgStructure.CurrentWindow->Window.VisualInfo->visualid;
#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
/* Handle the OpenGL inquiries */
case GLUT_WINDOW_RGBA:
glGetBooleanv ( GL_RGBA_MODE, &boolValue );
returnValue = boolValue ? 1 : 0;
return returnValue;
case GLUT_WINDOW_DOUBLEBUFFER:
glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue );
returnValue = boolValue ? 1 : 0;
return returnValue;
case GLUT_WINDOW_STEREO:
glGetBooleanv ( GL_STEREO, &boolValue );
returnValue = boolValue ? 1 : 0;
return returnValue;
case GLUT_WINDOW_RED_SIZE:
glGetIntegerv ( GL_RED_BITS, &returnValue );
return returnValue;
case GLUT_WINDOW_GREEN_SIZE:
glGetIntegerv ( GL_GREEN_BITS, &returnValue );
return returnValue;
case GLUT_WINDOW_BLUE_SIZE:
glGetIntegerv ( GL_BLUE_BITS, &returnValue );
return returnValue;
case GLUT_WINDOW_ALPHA_SIZE:
glGetIntegerv ( GL_ALPHA_BITS, &returnValue );
return returnValue;
case GLUT_WINDOW_ACCUM_RED_SIZE:
glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue );
return returnValue;
case GLUT_WINDOW_ACCUM_GREEN_SIZE:
glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue );
return returnValue;
case GLUT_WINDOW_ACCUM_BLUE_SIZE:
glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue );
return returnValue;
case GLUT_WINDOW_ACCUM_ALPHA_SIZE:
glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue );
return returnValue;
case GLUT_WINDOW_DEPTH_SIZE:
glGetIntegerv ( GL_DEPTH_BITS, &returnValue );
return returnValue;
case GLUT_WINDOW_BUFFER_SIZE:
returnValue = 1 ; /* ????? */
return returnValue;
case GLUT_WINDOW_STENCIL_SIZE:
returnValue = 0 ; /* ????? */
return returnValue;
case GLUT_WINDOW_X:
case GLUT_WINDOW_Y:
case GLUT_WINDOW_WIDTH:
case GLUT_WINDOW_HEIGHT:
{
/*
* There is considerable confusion about the "right thing to
* do" concerning window size and position. GLUT itself is
* not consistent between Windows and UNIX/X11; since
* platform independence is a virtue for "freeglut", we
* decided to break with GLUT's behaviour.
*
* Under UNIX/X11, it is apparently not possible to get the
* window border sizes in order to subtract them off the
* window's initial position until some time after the window
* has been created. Therefore we decided on the following
* 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
* (w,h).
* - When you query the size and position of the window--as
* is happening here for Windows--"freeglut" will return
* the size of the drawable area--the (w,h) that you
* specified when you created the window--and the coordinates
* of the upper left hand corner of the drawable
* area--which is NOT the (x,y) you specified.
*/
RECT winRect;
freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 );
/*
* We need to call GetWindowRect() first...
* (this returns the pixel coordinates of the outside of the window)
*/
GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect );
/* ...then we've got to correct the results we've just received... */
#if !TARGET_HOST_WINCE
if ( ( fgStructure.GameMode != fgStructure.CurrentWindow ) && ( fgStructure.CurrentWindow->Parent == NULL ) &&
( ! fgStructure.CurrentWindow->IsMenu ) )
{
winRect.left += GetSystemMetrics( SM_CXSIZEFRAME );
winRect.right -= GetSystemMetrics( SM_CXSIZEFRAME );
winRect.top += GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION );
winRect.bottom -= GetSystemMetrics( SM_CYSIZEFRAME );
}
#endif /* !TARGET_HOST_WINCE */
switch( eWhat )
{
case GLUT_WINDOW_X: return winRect.left ;
case GLUT_WINDOW_Y: return winRect.top ;
case GLUT_WINDOW_WIDTH: return winRect.right - winRect.left;
case GLUT_WINDOW_HEIGHT: return winRect.bottom - winRect.top;
}
}
break;
case GLUT_WINDOW_BORDER_WIDTH :
#if TARGET_HOST_WINCE
return 0;
#else
return GetSystemMetrics( SM_CXSIZEFRAME );
#endif /* !TARGET_HOST_WINCE */
case GLUT_WINDOW_HEADER_HEIGHT :
#if TARGET_HOST_WINCE
return 0;
#else
return GetSystemMetrics( SM_CYCAPTION );
#endif /* TARGET_HOST_WINCE */
case GLUT_DISPLAY_MODE_POSSIBLE:
#if TARGET_HOST_WINCE
return GL_FALSE;
#else
return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE,
PFD_MAIN_PLANE );
#endif /* TARGET_HOST_WINCE */
case GLUT_WINDOW_FORMAT_ID:
#if !TARGET_HOST_WINCE
if( fgStructure.CurrentWindow != NULL )
return GetPixelFormat( fgStructure.CurrentWindow->Window.Device );
#endif /* TARGET_HOST_WINCE */
return 0;
#endif
/* The window structure queries */
case GLUT_WINDOW_PARENT:
if( fgStructure.CurrentWindow == NULL ) return 0;
if( fgStructure.CurrentWindow->Parent == NULL ) return 0;
return fgStructure.CurrentWindow->Parent->ID;
case GLUT_WINDOW_NUM_CHILDREN:
if( fgStructure.CurrentWindow == NULL )
return 0;
return fgListLength( &fgStructure.CurrentWindow->Children );
case GLUT_WINDOW_CURSOR:
if( fgStructure.CurrentWindow == NULL )
return 0;
return fgStructure.CurrentWindow->State.Cursor;
case GLUT_MENU_NUM_ITEMS:
if( fgStructure.CurrentMenu == NULL )
return 0;
return fgListLength( &fgStructure.CurrentMenu->Entries );
case GLUT_ACTION_ON_WINDOW_CLOSE:
return fgState.ActionOnWindowClose;
case GLUT_VERSION :
return VERSION_MAJOR * 10000 + VERSION_MINOR * 100 + VERSION_PATCH;
case GLUT_RENDERING_CONTEXT:
return fgState.UseCurrentContext ? GLUT_USE_CURRENT_CONTEXT
: GLUT_CREATE_NEW_CONTEXT;
case GLUT_DIRECT_RENDERING:
return fgState.DirectContext;
break;
default:
fgWarning( "glutGet(): missing enum handle %d", eWhat );
break;
}
return -1;
}
/*
* Returns various device information.
*/
int FGAPIENTRY glutDeviceGet( GLenum eWhat )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDeviceGet" );
/* XXX WARNING: we are mostly lying in this function. */
switch( eWhat )
{
case GLUT_HAS_KEYBOARD:
/*
* We always have a keyboard present on PC machines...
*
* XXX I think that some of my PCs will boot without a keyboard.
* XXX Also, who says that we are running on a PC? UNIX/X11
* XXX is much more generic, and X11 can go over a network.
* XXX Though in actuality, we can probably assume BOTH a
* XXX mouse and keyboard for most/all of our users.
*/
return TRUE ;
#if TARGET_HOST_UNIX_X11
case GLUT_HAS_MOUSE:
return TRUE ;
case GLUT_NUM_MOUSE_BUTTONS:
/*
* Return the number of mouse buttons available. This is a big guess.
*
* XXX We can probe /var/run/dmesg.boot which is world-readable.
* XXX This would be somewhat system-dependant, but is doable.
* XXX E.g., on NetBSD, my USB mouse registers:
* XXX ums0 at uhidev0: 3 buttons and Z dir.
* XXX We can also probe /var/log/XFree86\..*\.log to get
* XXX lines such as:
* XXX (**) Option "Buttons" "5"
* XXX (**) Option "ZAxisMapping" "4 5"
* XXX (**) Mouse0: ZAxisMapping: buttons 4 and 5
* XXX (**) Mouse0: Buttons: 5
* XXX ...which tells us even more, and is a bit less
* XXX system-dependant. (Other than MS-WINDOWS, all
* XXX target hosts with actual users are probably running
* XXX XFree86...) It is at least worth taking a look at
* XXX this file.
*/
return 3 ;
#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
case GLUT_HAS_MOUSE:
/*
* The Windows can be booted without a mouse.
* It would be nice to have this reported.
*/
return GetSystemMetrics( SM_MOUSEPRESENT );
case GLUT_NUM_MOUSE_BUTTONS:
/* We are much more fortunate under Win32 about this... */
#if TARGET_HOST_WINCE
return 1;
#else
return GetSystemMetrics( SM_CMOUSEBUTTONS );
#endif /* TARGET_HOST_WINCE */
#endif
case GLUT_HAS_JOYSTICK:
return fgJoystickDetect ();
case GLUT_OWNS_JOYSTICK:
return fgState.JoysticksInitialised;
case GLUT_JOYSTICK_POLL_RATE:
return fgStructure.CurrentWindow ? fgStructure.CurrentWindow->State.JoystickPollRate : 0;
/* XXX The following two are only for Joystick 0 but this is an improvement */
case GLUT_JOYSTICK_BUTTONS:
return glutJoystickGetNumButtons ( 0 );
case GLUT_JOYSTICK_AXES:
return glutJoystickGetNumAxes ( 0 );
case GLUT_HAS_SPACEBALL:
case GLUT_HAS_DIAL_AND_BUTTON_BOX:
case GLUT_HAS_TABLET:
return FALSE;
case GLUT_NUM_SPACEBALL_BUTTONS:
case GLUT_NUM_BUTTON_BOX_BUTTONS:
case GLUT_NUM_DIALS:
case GLUT_NUM_TABLET_BUTTONS:
return 0;
case GLUT_DEVICE_IGNORE_KEY_REPEAT:
return fgStructure.CurrentWindow ? fgStructure.CurrentWindow->State.IgnoreKeyRepeat : 0;
case GLUT_DEVICE_KEY_REPEAT:
return fgState.KeyRepeat;
default:
fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
break;
}
/* And now -- the failure. */
return -1;
}
/*
* This should return the current state of ALT, SHIFT and CTRL keys.
*/
int FGAPIENTRY glutGetModifiers( void )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGetModifiers" );
if( fgState.Modifiers == 0xffffffff )
{
fgWarning( "glutGetModifiers() called outside an input callback" );
return 0;
}
return fgState.Modifiers;
}
/*
* Return the state of the GLUT API overlay subsystem. A misery ;-)
*/
int FGAPIENTRY glutLayerGet( GLenum eWhat )
{
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutLayerGet" );
/*
* This is easy as layers are not implemented ;-)
*
* XXX Can we merge the UNIX/X11 and WIN32 sections? Or
* XXX is overlay support planned?
*/
switch( eWhat )
{
#if TARGET_HOST_UNIX_X11
case GLUT_OVERLAY_POSSIBLE:
return FALSE;
case GLUT_LAYER_IN_USE:
return GLUT_NORMAL;
case GLUT_HAS_OVERLAY:
return FALSE;
case GLUT_TRANSPARENT_INDEX:
/*
* Return just anything, which is always defined as zero
*
* XXX HUH?
*/
return 0;
case GLUT_NORMAL_DAMAGED:
/* XXX Actually I do not know. Maybe. */
return FALSE;
case GLUT_OVERLAY_DAMAGED:
return -1;
#elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE
case GLUT_OVERLAY_POSSIBLE:
/* return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE,
PFD_OVERLAY_PLANE ); */
return FALSE ;
case GLUT_LAYER_IN_USE:
return GLUT_NORMAL;
case GLUT_HAS_OVERLAY:
return FALSE;
case GLUT_TRANSPARENT_INDEX:
/*
* Return just anything, which is always defined as zero
*
* XXX HUH?
*/
return 0;
case GLUT_NORMAL_DAMAGED:
/* XXX Actually I do not know. Maybe. */
return FALSE;
case GLUT_OVERLAY_DAMAGED:
return -1;
#endif
default:
fgWarning( "glutLayerGet(): missing enum handle %d", eWhat );
break;
}
/* And fail. That's good. Programs do love failing. */
return -1;
}
/*** 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

@ -0,0 +1,590 @@
/*
* freeglut_structure.c
*
* Windows and menus need tree structure
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Sat Dec 18 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.
*/
#include <GL/freeglut.h>
#include "freeglut_internal.h"
/* -- GLOBAL EXPORTS ------------------------------------------------------- */
/*
* The SFG_Structure container holds information about windows and menus
* created between glutInit() and glutMainLoop() return.
*/
SFG_Structure fgStructure = { { NULL, NULL }, /* The list of windows */
{ NULL, NULL }, /* The list of menus */
{ NULL, NULL }, /* Windows to Destroy list */
NULL, /* The current window */
NULL, /* The current menu */
NULL, /* The menu OpenGL context */
NULL, /* The game mode window */
0, /* The current new window ID */
0 }; /* The current new menu ID */
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
static void fghClearCallBacks( SFG_Window *window )
{
if( window )
{
int i;
for( i = 0; i < TOTAL_CALLBACKS; ++i )
window->CallBacks[ i ] = NULL;
}
}
/*
* This private function creates, opens and adds to the hierarchy
* a freeglut window complete with OpenGL context and stuff...
*
* If parent is set to NULL, the window created will be a topmost one.
*/
SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title,
int x, int y, int w, int h,
GLboolean gameMode, GLboolean isMenu )
{
/* Have the window object created */
SFG_Window *window = (SFG_Window *)calloc( sizeof(SFG_Window), 1 );
fghClearCallBacks( window );
/* Initialize the object properties */
window->ID = ++fgStructure.WindowID;
window->State.OldHeight = window->State.OldWidth = -1;
fgListInit( &window->Children );
if( parent )
{
fgListAppend( &parent->Children, &window->Node );
window->Parent = parent;
}
else
fgListAppend( &fgStructure.Windows, &window->Node );
/* Set the default mouse cursor and reset the modifiers value */
window->State.Cursor = GLUT_CURSOR_INHERIT;
window->IsMenu = isMenu;
window->State.IgnoreKeyRepeat = GL_FALSE;
window->State.KeyRepeating = GL_FALSE;
/*
* Open the window now. The fgOpenWindow() function is system
* dependant, and resides in freeglut_window.c. Uses fgState.
*/
fgOpenWindow( window, title, x, y, w, h, gameMode,
(GLboolean)(parent ? GL_TRUE : GL_FALSE) );
return window;
}
/*
* This private function creates a menu and adds it to the menus list
*/
SFG_Menu* fgCreateMenu( FGCBMenu menuCallback )
{
int x = 100, y = 100, w = 100, h = 100;
SFG_Window *current_window = fgStructure.CurrentWindow;
/* Have the menu object created */
SFG_Menu* menu = (SFG_Menu *)calloc( sizeof(SFG_Menu), 1 );
menu->ParentWindow = NULL;
/* Create a window for the menu to reside in. */
fgCreateWindow( NULL, "freeglut menu", x, y, w, h, GL_FALSE, GL_TRUE );
menu->Window = fgStructure.CurrentWindow;
glutDisplayFunc( fgDisplayMenu );
glutHideWindow( ); /* Hide the window for now */
fgSetWindow( current_window );
/* Initialize the object properties: */
menu->ID = ++fgStructure.MenuID;
menu->Callback = menuCallback;
menu->ActiveEntry = NULL;
fgListInit( &menu->Entries );
fgListAppend( &fgStructure.Menus, &menu->Node );
/* Newly created menus implicitly become current ones */
fgStructure.CurrentMenu = menu;
return menu;
}
/*
* Function to add a window to the linked list of windows to destroy.
* Subwindows are automatically added because they hang from the window
* structure.
*/
void fgAddToWindowDestroyList( SFG_Window* window )
{
SFG_WindowList *new_list_entry =
( SFG_WindowList* )malloc( sizeof(SFG_WindowList ) );
new_list_entry->window = window;
fgListAppend( &fgStructure.WindowsToDestroy, &new_list_entry->node );
/* Check if the window is the current one... */
if( fgStructure.CurrentWindow == window )
fgStructure.CurrentWindow = NULL;
/*
* Clear all window callbacks except Destroy, which will
* be invoked later. Right now, we are potentially carrying
* out a freeglut operation at the behest of a client callback,
* so we are reluctant to re-enter the client with the Destroy
* callback, right now. The others are all wiped out, however,
* to ensure that they are no longer called after this point.
*/
{
FGCBDestroy destroy = (FGCBDestroy)FETCH_WCB( *window, Destroy );
fghClearCallBacks( window );
SET_WCB( *window, Destroy, destroy );
}
}
/*
* Function to close down all the windows in the "WindowsToDestroy" list
*/
void fgCloseWindows( )
{
while( fgStructure.WindowsToDestroy.First )
{
SFG_WindowList *window_ptr = fgStructure.WindowsToDestroy.First;
fgDestroyWindow( window_ptr->window );
fgListRemove( &fgStructure.WindowsToDestroy, &window_ptr->node );
free( window_ptr );
}
}
/*
* This function destroys a window and all of its subwindows. Actually,
* another function, defined in freeglut_window.c is called, but this is
* a whole different story...
*/
void fgDestroyWindow( SFG_Window* window )
{
FREEGLUT_INTERNAL_ERROR_EXIT ( window, "Window destroy function called with null window",
"fgDestroyWindow" );
while( window->Children.First )
fgDestroyWindow( ( SFG_Window * )window->Children.First );
{
SFG_Window *activeWindow = fgStructure.CurrentWindow;
INVOKE_WCB( *window, Destroy, ( ) );
fgSetWindow( activeWindow );
}
if( window->Parent )
fgListRemove( &window->Parent->Children, &window->Node );
else
fgListRemove( &fgStructure.Windows, &window->Node );
if( window->ActiveMenu )
fgDeactivateMenu( window );
fghClearCallBacks( window );
fgCloseWindow( window );
free( window );
if( fgStructure.CurrentWindow == window )
fgStructure.CurrentWindow = NULL;
}
/*
* This is a helper static function that removes a menu (given its pointer)
* from any windows that can be accessed from a given parent...
*/
static void fghRemoveMenuFromWindow( SFG_Window* window, SFG_Menu* menu )
{
SFG_Window *subWindow;
int i;
/* Check whether this is the active menu in the window */
if ( menu == window->ActiveMenu )
window->ActiveMenu = NULL ;
/*
* Check if the menu is attached to the current window,
* if so, have it detached (by overwriting with a NULL):
*/
for( i = 0; i < FREEGLUT_MAX_MENUS; i++ )
if( window->Menu[ i ] == menu )
window->Menu[ i ] = NULL;
/* Call this function for all of the window's children recursively: */
for( subWindow = (SFG_Window *)window->Children.First;
subWindow;
subWindow = (SFG_Window *)subWindow->Node.Next)
fghRemoveMenuFromWindow( subWindow, menu );
}
/*
* This is a static helper function that removes menu references
* from another menu, given two pointers to them...
*/
static void fghRemoveMenuFromMenu( SFG_Menu* from, SFG_Menu* menu )
{
SFG_MenuEntry *entry;
for( entry = (SFG_MenuEntry *)from->Entries.First;
entry;
entry = ( SFG_MenuEntry * )entry->Node.Next )
if( entry->SubMenu == menu )
entry->SubMenu = NULL;
}
/*
* This function destroys a menu specified by the parameter. All menus
* and windows are updated to make sure no ill pointers hang around.
*/
void fgDestroyMenu( SFG_Menu* menu )
{
SFG_Window *window;
SFG_Menu *from;
FREEGLUT_INTERNAL_ERROR_EXIT ( menu, "Menu destroy function called with null menu",
"fgDestroyMenu" );
/* First of all, have all references to this menu removed from all windows: */
for( window = (SFG_Window *)fgStructure.Windows.First;
window;
window = (SFG_Window *)window->Node.Next )
fghRemoveMenuFromWindow( window, menu );
/* Now proceed with removing menu entries that lead to this menu */
for( from = ( SFG_Menu * )fgStructure.Menus.First;
from;
from = ( SFG_Menu * )from->Node.Next )
fghRemoveMenuFromMenu( from, menu );
/*
* If the programmer defined a destroy callback, call it
* A. Donev: But first make this the active menu
*/
if( menu->Destroy )
{
SFG_Menu *activeMenu=fgStructure.CurrentMenu;
fgStructure.CurrentMenu = menu;
menu->Destroy( );
fgStructure.CurrentMenu = activeMenu;
}
/*
* Now we are pretty sure the menu is not used anywhere
* and that we can remove all of its entries
*/
while( menu->Entries.First )
{
SFG_MenuEntry *entry = ( SFG_MenuEntry * ) menu->Entries.First;
fgListRemove( &menu->Entries, &entry->Node );
if( entry->Text )
free( entry->Text );
entry->Text = NULL;
free( entry );
}
if( fgStructure.CurrentWindow == menu->Window )
fgSetWindow( NULL );
fgDestroyWindow( menu->Window );
fgListRemove( &fgStructure.Menus, &menu->Node );
if( fgStructure.CurrentMenu == menu )
fgStructure.CurrentMenu = NULL;
free( menu );
}
/*
* This function should be called on glutInit(). It will prepare the internal
* structure of freeglut to be used in the application. The structure will be
* destroyed using fgDestroyStructure() on glutMainLoop() return. In that
* case further use of freeglut should be preceeded with a glutInit() call.
*/
void fgCreateStructure( void )
{
/*
* We will be needing two lists: the first containing windows,
* and the second containing the user-defined menus.
* Also, no current window/menu is set, as none has been created yet.
*/
fgListInit(&fgStructure.Windows);
fgListInit(&fgStructure.Menus);
fgListInit(&fgStructure.WindowsToDestroy);
fgStructure.CurrentWindow = NULL;
fgStructure.CurrentMenu = NULL;
fgStructure.MenuContext = NULL;
fgStructure.GameMode = NULL;
fgStructure.WindowID = 0;
fgStructure.MenuID = 0;
}
/*
* This function is automatically called on glutMainLoop() return.
* It should deallocate and destroy all remnants of previous
* glutInit()-enforced structure initialization...
*/
void fgDestroyStructure( void )
{
/* Clean up the WindowsToDestroy list. */
fgCloseWindows( );
/* Make sure all windows and menus have been deallocated */
while( fgStructure.Menus.First )
fgDestroyMenu( ( SFG_Menu * )fgStructure.Menus.First );
while( fgStructure.Windows.First )
fgDestroyWindow( ( SFG_Window * )fgStructure.Windows.First );
}
/*
* Helper function to enumerate through all registered top-level windows
*/
void fgEnumWindows( FGCBenumerator enumCallback, SFG_Enumerator* enumerator )
{
SFG_Window *window;
FREEGLUT_INTERNAL_ERROR_EXIT ( enumCallback && enumerator,
"Enumerator or callback missing from window enumerator call",
"fgEnumWindows" );
/* Check every of the top-level windows */
for( window = ( SFG_Window * )fgStructure.Windows.First;
window;
window = ( SFG_Window * )window->Node.Next )
{
enumCallback( window, 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,
SFG_Enumerator* enumerator )
{
SFG_Window *child;
FREEGLUT_INTERNAL_ERROR_EXIT ( enumCallback && enumerator,
"Enumerator or callback missing from subwindow enumerator call",
"fgEnumSubWindows" );
FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Window Enumeration" );
for( child = ( SFG_Window * )window->Children.First;
child;
child = ( SFG_Window * )child->Node.Next )
{
enumCallback( child, enumerator );
if( enumerator->found )
return;
}
}
/*
* A static helper function to look for a window given its handle
*/
static void fghcbWindowByHandle( SFG_Window *window,
SFG_Enumerator *enumerator )
{
if ( enumerator->found )
return;
/* Check the window's handle. Hope this works. Looks ugly. That's for sure. */
if( window->Window.Handle == (SFG_WindowHandleType) (enumerator->data) )
{
enumerator->found = GL_TRUE;
enumerator->data = window;
return;
}
/* Otherwise, b2Assert this window's children */
fgEnumSubWindows( window, fghcbWindowByHandle, 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.
*/
SFG_Window* fgWindowByHandle ( SFG_WindowHandleType hWindow )
{
SFG_Enumerator enumerator;
/* This is easy and makes use of the windows enumeration defined above */
enumerator.found = GL_FALSE;
enumerator.data = (void *)hWindow;
fgEnumWindows( fghcbWindowByHandle, &enumerator );
if( enumerator.found )
return( SFG_Window *) enumerator.data;
return NULL;
}
/*
* A static helper function to look for a window given its ID
*/
static void fghcbWindowByID( SFG_Window *window, SFG_Enumerator *enumerator )
{
/* Make sure we do not overwrite our precious results... */
if( enumerator->found )
return;
/* Check the window's handle. Hope this works. Looks ugly. That's for sure. */
if( window->ID == *( int *)(enumerator->data) )
{
enumerator->found = GL_TRUE;
enumerator->data = window;
return;
}
/* Otherwise, b2Assert this window's children */
fgEnumSubWindows( window, fghcbWindowByID, enumerator );
}
/*
* This function is similiar to the previous one, except it is
* looking for a specified (sub)window identifier. The function
* is defined in freeglut_structure.c file.
*/
SFG_Window* fgWindowByID( int windowID )
{
SFG_Enumerator enumerator;
/* Uses a method very similiar for fgWindowByHandle... */
enumerator.found = GL_FALSE;
enumerator.data = ( void * )&windowID;
fgEnumWindows( fghcbWindowByID, &enumerator );
if( enumerator.found )
return ( SFG_Window * )enumerator.data;
return NULL;
}
/*
* Looks up a menu given its ID. This is easier that fgWindowByXXX
* as all menus are placed in one doubly linked list...
*/
SFG_Menu* fgMenuByID( int menuID )
{
SFG_Menu *menu = NULL;
/* It's enough to b2Assert 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;
return NULL;
}
/*
* List functions...
*/
void fgListInit(SFG_List *list)
{
list->First = NULL;
list->Last = NULL;
}
void fgListAppend(SFG_List *list, SFG_Node *node)
{
if ( list->Last )
{
SFG_Node *ln = (SFG_Node *) list->Last;
ln->Next = node;
node->Prev = ln;
}
else
{
node->Prev = NULL;
list->First = node;
}
node->Next = NULL;
list->Last = node;
}
void fgListRemove(SFG_List *list, SFG_Node *node)
{
if( node->Next )
( ( SFG_Node * )node->Next )->Prev = node->Prev;
if( node->Prev )
( ( SFG_Node * )node->Prev )->Next = node->Next;
if( ( ( SFG_Node * )list->First ) == node )
list->First = node->Next;
if( ( ( SFG_Node * )list->Last ) == node )
list->Last = node->Prev;
}
int fgListLength(SFG_List *list)
{
SFG_Node *node;
int length = 0;
for( node =( SFG_Node * )list->First;
node;
node = ( SFG_Node * )node->Next )
++length;
return length;
}
void fgListInsert(SFG_List *list, SFG_Node *next, SFG_Node *node)
{
SFG_Node *prev;
if( (node->Next = next) )
{
prev = next->Prev;
next->Prev = node;
}
else
{
prev = list->Last;
list->Last = node;
}
if( (node->Prev = prev) )
prev->Next = node;
else
list->First = node;
}
/*** END OF FILE ***/

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 TARGET_HOST_WINCE
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 TARGET_HOST_WINCE
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 /* TARGET_HOST_WINCE */
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

View File

@ -0,0 +1,50 @@
/*
* freeglut_videoresize.c
*
* Video resize functions (as defined by GLUT API)
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 16 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.
*/
#include <GL/freeglut.h>
#include "freeglut_internal.h"
/*
* NOTE: functions declared in this file probably will not be implemented.
*/
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
int FGAPIENTRY glutVideoResizeGet( GLenum eWhat ) { return( 0x00 ); }
void FGAPIENTRY glutSetupVideoResizing( void ) { /* Not implemented */ }
void FGAPIENTRY glutStopVideoResizing( void ) { /* Not implemented */ }
void FGAPIENTRY glutVideoResize( int x, int y, int w, int h ) { /* Not implemented */ }
void FGAPIENTRY glutVideoPan( int x, int y, int w, int h ) { /* Not implemented */ }
/*** END OF FILE ***/

File diff suppressed because it is too large Load Diff