Changed all references to the 'freeglut-1.3' directory to 'src', copied 'freeglut...
authorEric Sandall <sandalle@gmail.com>
Mon, 23 Jun 2003 23:40:12 +0000 (23:40 +0000)
committerEric Sandall <sandalle@gmail.com>
Mon, 23 Jun 2003 23:40:12 +0000 (23:40 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@98 7f0cb862-5218-0410-a997-914c9d46530a

37 files changed:
ChangeLog
Makefile.am
TODO
configure.in
freeglut.dsp
freeglut.kdevprj
freeglut13.dsp
freeglut13.plg
freeglut_static.dsp
freeglutdll.dsp
src/Makefile.am [new file with mode: 0644]
src/freeglut_callbacks.c [new file with mode: 0644]
src/freeglut_cursor.c [new file with mode: 0644]
src/freeglut_display.c [new file with mode: 0644]
src/freeglut_ext.c [new file with mode: 0644]
src/freeglut_font.c [new file with mode: 0644]
src/freeglut_font_data.c [new file with mode: 0644]
src/freeglut_gamemode.c [new file with mode: 0644]
src/freeglut_geometry.c [new file with mode: 0644]
src/freeglut_init.c [new file with mode: 0644]
src/freeglut_internal.h [new file with mode: 0644]
src/freeglut_joystick.c [new file with mode: 0644]
src/freeglut_main.c [new file with mode: 0644]
src/freeglut_menu.c [new file with mode: 0644]
src/freeglut_misc.c [new file with mode: 0644]
src/freeglut_overlay.c [new file with mode: 0644]
src/freeglut_state.c [new file with mode: 0644]
src/freeglut_stroke_mono_roman.c [new file with mode: 0644]
src/freeglut_stroke_roman.c [new file with mode: 0644]
src/freeglut_structure.c [new file with mode: 0644]
src/freeglut_teapot.c [new file with mode: 0644]
src/freeglut_videoresize.c [new file with mode: 0644]
src/freeglut_window.c [new file with mode: 0644]
src/freeglutdll.def [new file with mode: 0644]
src/templates/cpp_template [new file with mode: 0644]
src/templates/header_template [new file with mode: 0644]
tests/Makefile.am

index c548d79..a5c5995 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -166,3 +166,5 @@ October 24, 2002:
 (60) Added autogen.sh (#30 from todo.txt)
 
 (70) Updated aclocal.m4 with aclocal 1.7.3 (was created with aclocal 1.5)
+
+(71) Changed all references to the 'freeglut-1.3' directory to 'src', copied 'freeglut-1.3' to 'src' and added all files to the repository (TODO #34).
index 2c25549..fdc20d9 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce makefile.im
 
-SUBDIRS = freeglut-1.3 include genfonts tests
+SUBDIRS = src include genfonts tests
 AUTOMAKE_OPTIONS = gnu
 
 EXTRA_DIST = AUTHORS COPYING ChangeLog INSTALL NEWS README TODO freeglut.lsm \
diff --git a/TODO b/TODO
index 74c4dbd..e871a03 100644 (file)
--- a/TODO
+++ b/TODO
@@ -52,7 +52,7 @@ autoconf
 
 *Fixed*(33) Also from Eero Pajarre:  A patch to prevent "freeglut" from adjusting for the window border thickness in game mode.
 
-(34) Change the name of the source directory from "freeglut-1.3" to "src".
+*Fixed*(34) Change the name of the source directory from "freeglut-1.3" to "src".
 
 <From the Web Page, dated January 16, 2000; I don't know how many of these have
 already been fixed.>
index c53d2a7..ce5c570 100644 (file)
@@ -27,4 +27,4 @@ dnl Checks for library functions.
 AC_CHECK_LIBM
 AC_SUBST(LIBM)
 
-AC_OUTPUT(Makefile freeglut-1.3/Makefile include/Makefile include/GL/Makefile genfonts/Makefile tests/Makefile )
+AC_OUTPUT(Makefile src/Makefile include/Makefile include/GL/Makefile genfonts/Makefile tests/Makefile )
index a27eb3a..c0b5ec9 100644 (file)
@@ -90,83 +90,83 @@ LINK32=link.exe
 # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_callbacks.c"
+SOURCE=".\src\freeglut_callbacks.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_cursor.c"
+SOURCE=".\src\freeglut_cursor.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_display.c"
+SOURCE=".\src\freeglut_display.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_font.c"
+SOURCE=".\src\freeglut_font.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_font_data.c"
+SOURCE=".\src\freeglut_font_data.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_gamemode.c"
+SOURCE=".\src\freeglut_gamemode.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_geometry.c"
+SOURCE=".\src\freeglut_geometry.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_init.c"
+SOURCE=".\src\freeglut_init.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_joystick.c"
+SOURCE=".\src\freeglut_joystick.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_main.c"
+SOURCE=".\src\freeglut_main.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_menu.c"
+SOURCE=".\src\freeglut_menu.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_misc.c"
+SOURCE=".\src\freeglut_misc.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_overlay.c"
+SOURCE=".\src\freeglut_overlay.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_state.c"
+SOURCE=".\src\freeglut_state.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_stroke_mono_roman.c"
+SOURCE=".\src\freeglut_stroke_mono_roman.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_stroke_roman.c"
+SOURCE=".\src\freeglut_stroke_roman.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_structure.c"
+SOURCE=".\src\freeglut_structure.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_teapot.c"
+SOURCE=".\src\freeglut_teapot.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_videoresize.c"
+SOURCE=".\src\freeglut_videoresize.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_window.c"
+SOURCE=".\src\freeglut_window.c"
 # End Source File
 # End Group
 # Begin Group "Header Files"
@@ -182,7 +182,7 @@ SOURCE=.\include\GL\freeglut_ext.h
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_internal.h"
+SOURCE=".\src\freeglut_internal.h"
 # End Source File
 # Begin Source File
 
index 88edf33..b4d4cf7 100644 (file)
@@ -9,23 +9,23 @@ files=include/GL/freeglut.h,include/GL/freeglut_internal.h,
 sub_dirs=
 type=normal
 [Workspace_1]
-openfiles=Nienazwany.h,Nienazwany.cpp,/home/olszta/freeglut/include/GL/freeglut_internal.h,/home/olszta/freeglut/freeglut-1.3/freeglut_callbacks.c,/home/olszta/freeglut/freeglut-1.3/freeglut_gamemode.c,/home/olszta/freeglut/freeglut-1.3/freeglut_init.c,/home/olszta/freeglut/freeglut-1.3/freeglut_main.c,/home/olszta/freeglut/freeglut-1.3/freeglut_window.c,/home/olszta/freeglut/freeglut-1.3/freeglut_misc.c,/home/olszta/freeglut/include/GL/freeglut.h,/home/olszta/freeglut/freeglut-1.3/freeglut_cursor.c,/home/olszta/freeglut/freeglut-1.3/freeglut_geometry.c,/home/olszta/freeglut/freeglut-1.3/freeglut_font_data.c,/home/olszta/freeglut/freeglut-1.3/freeglut_videoresize.c,/home/olszta/freeglut/freeglut-1.3/freeglut_teapot.c,/home/olszta/freeglut/freeglut-1.3/freeglut_structure.c,/home/olszta/freeglut/freeglut-1.3/freeglut_state.c,
+openfiles=Nienazwany.h,Nienazwany.cpp,/home/olszta/freeglut/include/GL/freeglut_internal.h,/home/olszta/freeglut/src/freeglut_callbacks.c,/home/olszta/freeglut/src/freeglut_gamemode.c,/home/olszta/freeglut/src/freeglut_init.c,/home/olszta/freeglut/src/freeglut_main.c,/home/olszta/freeglut/src/freeglut_window.c,/home/olszta/freeglut/src/freeglut_misc.c,/home/olszta/freeglut/include/GL/freeglut.h,/home/olszta/freeglut/src/freeglut_cursor.c,/home/olszta/freeglut/src/freeglut_geometry.c,/home/olszta/freeglut/src/freeglut_font_data.c,/home/olszta/freeglut/src/freeglut_videoresize.c,/home/olszta/freeglut/src/freeglut_teapot.c,/home/olszta/freeglut/src/freeglut_structure.c,/home/olszta/freeglut/src/freeglut_state.c,
 show_outputview=true
 show_treeview=true
 header_file=/home/olszta/freeglut/include/GL/freeglut.h
-cpp_file=/home/olszta/freeglut/freeglut-1.3/freeglut_state.c
+cpp_file=/home/olszta/freeglut/src/freeglut_state.c
 browser_file=file:/usr/doc/kde/HTML/default/kdevelop/welcome/index.html
 [COPYING]
 install_location=
 dist=true
 install=false
 type=DATA
-[freeglut-1.3/freeglut_videoresize.c]
+[src/freeglut_videoresize.c]
 install_location=
 dist=true
 install=false
 type=SOURCE
-[freeglut-1.3/docs/Makefile.am]
+[src/docs/Makefile.am]
 type=normal
 sub_dirs=
 [Config for BinMakefileAm]
@@ -35,8 +35,8 @@ cxxflags=-O0 -g3 -Wall
 [po/Makefile.am]
 type=po
 sub_dirs=
-[freeglut-1.3/Makefile.am]
-files=freeglut-1.3/freeglut_callbacks.c,freeglut-1.3/freeglut_cursor.c,freeglut-1.3/freeglut_display.c,freeglut-1.3/freeglut_font.c,freeglut-1.3/freeglut_font_data.c,freeglut-1.3/freeglut_gamemode.c,freeglut-1.3/freeglut_geometry.c,freeglut-1.3/freeglut_init.c,freeglut-1.3/freeglut_joystick.c,freeglut-1.3/freeglut_main.c,freeglut-1.3/freeglut_menu.c,freeglut-1.3/freeglut_misc.c,freeglut-1.3/freeglut_overlay.c,freeglut-1.3/freeglut_state.c,freeglut-1.3/freeglut_structure.c,freeglut-1.3/freeglut_teapot.c,freeglut-1.3/freeglut_videoresize.c,freeglut-1.3/freeglut_window.c,
+[src/Makefile.am]
+files=src/freeglut_callbacks.c,src/freeglut_cursor.c,src/freeglut_display.c,src/freeglut_font.c,src/freeglut_font_data.c,src/freeglut_gamemode.c,src/freeglut_geometry.c,src/freeglut_init.c,src/freeglut_joystick.c,src/freeglut_main.c,src/freeglut_menu.c,src/freeglut_misc.c,src/freeglut_overlay.c,src/freeglut_state.c,src/freeglut_structure.c,src/freeglut_teapot.c,src/freeglut_videoresize.c,src/freeglut_window.c,
 type=prog_main
 sub_dirs=
 [freeglut.kdevprj]
@@ -49,12 +49,12 @@ install_location=
 dist=true
 install=false
 type=DATA
-[freeglut-1.3/freeglut_gamemode.c]
+[src/freeglut_gamemode.c]
 install_location=
 dist=true
 install=false
 type=SOURCE
-[freeglut-1.3/freeglut_menu.c]
+[src/freeglut_menu.c]
 install_location=
 dist=true
 install=false
@@ -65,30 +65,30 @@ Others=*,
 groups=Headers,Sources,GNU,Others,
 Sources=*.cpp,*.c,*.cc,*.C,*.cxx,*.ec,*.ecpp,*.lxx,*.l++,*.ll,*.l,
 Headers=*.h,*.hxx,*.hpp,*.H,
-[freeglut-1.3/docs/en/Makefile.am]
+[src/docs/en/Makefile.am]
 type=normal
 sub_dirs=
-[freeglut-1.3/freeglut_font.c]
+[src/freeglut_font.c]
 install_location=
 dist=true
 install=false
 type=SOURCE
-[freeglut-1.3/freeglut_window.c]
+[src/freeglut_window.c]
 install_location=
 dist=true
 install=false
 type=SOURCE
-[freeglut-1.3/freeglut_main.c]
+[src/freeglut_main.c]
 install_location=
 dist=true
 install=false
 type=SOURCE
-[freeglut-1.3/freeglut_state.c]
+[src/freeglut_state.c]
 install_location=
 dist=true
 install=false
 type=SOURCE
-[freeglut-1.3/freeglut_callbacks.c]
+[src/freeglut_callbacks.c]
 install_location=
 dist=true
 install=false
@@ -98,7 +98,7 @@ install_location=
 dist=true
 install=false
 type=HEADER
-[freeglut-1.3/freeglut_structure.c]
+[src/freeglut_structure.c]
 install_location=
 dist=true
 install=false
@@ -108,17 +108,17 @@ install_location=
 dist=true
 install=false
 type=DATA
-[freeglut-1.3/freeglut_geometry.c]
+[src/freeglut_geometry.c]
 install_location=
 dist=true
 install=false
 type=SOURCE
 [General]
-makefiles=Makefile.am,freeglut-1.3/Makefile.am,freeglut-1.3/docs/Makefile.am,freeglut-1.3/docs/en/Makefile.am,po/Makefile.am,include/Makefile.am,
+makefiles=Makefile.am,src/Makefile.am,src/docs/Makefile.am,src/docs/en/Makefile.am,po/Makefile.am,include/Makefile.am,
 version_control=None
 project_type=normal_empty
 author=Pawel W. Olszta
-sub_dir=freeglut-1.3/
+sub_dir=src/
 lfv_open_groups=Headers,Sources,
 workspace=1
 project_name=freeglut
@@ -135,17 +135,17 @@ install_location=
 dist=true
 install=false
 type=DATA
-[freeglut-1.3/freeglut_init.c]
+[src/freeglut_init.c]
 install_location=
 dist=true
 install=false
 type=SOURCE
-[freeglut-1.3/freeglut_display.c]
+[src/freeglut_display.c]
 install_location=
 dist=true
 install=false
 type=SOURCE
-[freeglut-1.3/freeglut_overlay.c]
+[src/freeglut_overlay.c]
 install_location=
 dist=true
 install=false
@@ -155,7 +155,7 @@ install_location=
 dist=true
 install=false
 type=DATA
-[freeglut-1.3/freeglut_misc.c]
+[src/freeglut_misc.c]
 install_location=
 dist=true
 install=false
@@ -163,8 +163,8 @@ type=SOURCE
 [Makefile.am]
 files=freeglut.kdevprj,AUTHORS,COPYING,ChangeLog,INSTALL,README,TODO,freeglut.lsm,
 type=normal
-sub_dirs=freeglut-1.3,include,
-[freeglut-1.3/freeglut_cursor.c]
+sub_dirs=src,include,
+[src/freeglut_cursor.c]
 install_location=
 dist=true
 install=false
index c585da1..2d0495e 100755 (executable)
@@ -91,75 +91,75 @@ LINK32=link.exe
 # PROP Default_Filter "*.c"
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_callbacks.c"
+SOURCE=".\src\freeglut_callbacks.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_cursor.c"
+SOURCE=".\src\freeglut_cursor.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_display.c"
+SOURCE=".\src\freeglut_display.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_font.c"
+SOURCE=".\src\freeglut_font.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_font_data.c"
+SOURCE=".\src\freeglut_font_data.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_gamemode.c"
+SOURCE=".\src\freeglut_gamemode.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_geometry.c"
+SOURCE=".\src\freeglut_geometry.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_init.c"
+SOURCE=".\src\freeglut_init.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_joystick.c"
+SOURCE=".\src\freeglut_joystick.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_main.c"
+SOURCE=".\src\freeglut_main.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_menu.c"
+SOURCE=".\src\freeglut_menu.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_misc.c"
+SOURCE=".\src\freeglut_misc.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_overlay.c"
+SOURCE=".\src\freeglut_overlay.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_state.c"
+SOURCE=".\src\freeglut_state.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_structure.c"
+SOURCE=".\src\freeglut_structure.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_teapot.c"
+SOURCE=".\src\freeglut_teapot.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_videoresize.c"
+SOURCE=".\src\freeglut_videoresize.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_window.c"
+SOURCE=".\src\freeglut_window.c"
 # End Source File
 # End Group
 # Begin Group "Headers"
index f8c5ceb..2c77efb 100755 (executable)
@@ -12,9 +12,9 @@ Project's tools are:
                        "<Component 0xa>" with flags ""
 
 Creating temp file "C:\WINDOWS\TEMP\RSP170.TMP" with contents </nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Fp"Debug/freeglut13.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /c 
-"C:\Project\freeglut\freeglut-1.3\freeglut_display.c"
-"C:\Project\freeglut\freeglut-1.3\freeglut_font.c"
-"C:\Project\freeglut\freeglut-1.3\freeglut_main.c"
+"C:\Project\freeglut\src\freeglut_display.c"
+"C:\Project\freeglut\src\freeglut_font.c"
+"C:\Project\freeglut\src\freeglut_main.c"
 >
 Creating command line "cl.exe @C:\WINDOWS\TEMP\RSP170.TMP" 
 Creating temp file "C:\WINDOWS\TEMP\RSP0171.TMP" with contents <kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"Debug/freeglut13.pdb" /debug /machine:I386 /out:"Debug/freeglut13.dll" /implib:"Debug/freeglut13.lib" /pdbtype:sept 
@@ -40,7 +40,7 @@ Creating command line "link.exe @C:\WINDOWS\TEMP\RSP0171.TMP"
 Compiling...
 freeglut_display.c
 freeglut_font.c
-C:\Project\freeglut\freeglut-1.3\freeglut_font.c(133) : fatal error C1189: #error :  glPushClientAttrib declaration missing
+C:\Project\freeglut\src\freeglut_font.c(133) : fatal error C1189: #error :  glPushClientAttrib declaration missing
 freeglut_main.c
 Error executing cl.exe.
 
index e20037b..3c2ef18 100644 (file)
@@ -85,83 +85,83 @@ LIB32=link.exe -lib
 # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_callbacks.c"
+SOURCE=".\src\freeglut_callbacks.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_cursor.c"
+SOURCE=".\src\freeglut_cursor.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_display.c"
+SOURCE=".\src\freeglut_display.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_font.c"
+SOURCE=".\src\freeglut_font.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_font_data.c"
+SOURCE=".\src\freeglut_font_data.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_gamemode.c"
+SOURCE=".\src\freeglut_gamemode.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_geometry.c"
+SOURCE=".\src\freeglut_geometry.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_init.c"
+SOURCE=".\src\freeglut_init.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_joystick.c"
+SOURCE=".\src\freeglut_joystick.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_main.c"
+SOURCE=".\src\freeglut_main.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_menu.c"
+SOURCE=".\src\freeglut_menu.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_misc.c"
+SOURCE=".\src\freeglut_misc.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_overlay.c"
+SOURCE=".\src\freeglut_overlay.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_state.c"
+SOURCE=".\src\freeglut_state.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_stroke_mono_roman.c"
+SOURCE=".\src\freeglut_stroke_mono_roman.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_stroke_roman.c"
+SOURCE=".\src\freeglut_stroke_roman.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_structure.c"
+SOURCE=".\src\freeglut_structure.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_teapot.c"
+SOURCE=".\src\freeglut_teapot.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_videoresize.c"
+SOURCE=".\src\freeglut_videoresize.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_window.c"
+SOURCE=".\src\freeglut_window.c"
 # End Source File
 # End Group
 # Begin Group "Header Files"
@@ -177,7 +177,7 @@ SOURCE=.\include\GL\freeglut_ext.h
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_internal.h"
+SOURCE=".\src\freeglut_internal.h"
 # End Source File
 # Begin Source File
 
index 1ca59db..91cec72 100644 (file)
@@ -90,83 +90,83 @@ LINK32=link.exe
 # PROP Default_Filter "*.c"
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_callbacks.c"
+SOURCE=".\src\freeglut_callbacks.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_cursor.c"
+SOURCE=".\src\freeglut_cursor.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_display.c"
+SOURCE=".\src\freeglut_display.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_font.c"
+SOURCE=".\src\freeglut_font.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_font_data.c"
+SOURCE=".\src\freeglut_font_data.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_gamemode.c"
+SOURCE=".\src\freeglut_gamemode.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_geometry.c"
+SOURCE=".\src\freeglut_geometry.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_init.c"
+SOURCE=".\src\freeglut_init.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_joystick.c"
+SOURCE=".\src\freeglut_joystick.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_main.c"
+SOURCE=".\src\freeglut_main.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_menu.c"
+SOURCE=".\src\freeglut_menu.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_misc.c"
+SOURCE=".\src\freeglut_misc.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_overlay.c"
+SOURCE=".\src\freeglut_overlay.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_state.c"
+SOURCE=".\src\freeglut_state.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_stroke_mono_roman.c"
+SOURCE=".\src\freeglut_stroke_mono_roman.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_stroke_roman.c"
+SOURCE=".\src\freeglut_stroke_roman.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_structure.c"
+SOURCE=".\src\freeglut_structure.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_teapot.c"
+SOURCE=".\src\freeglut_teapot.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_videoresize.c"
+SOURCE=".\src\freeglut_videoresize.c"
 # End Source File
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglut_window.c"
+SOURCE=".\src\freeglut_window.c"
 # End Source File
 # End Group
 # Begin Group "Headers"
@@ -183,7 +183,7 @@ SOURCE=.\include\Gl\freeglut_internal.h
 # End Group
 # Begin Source File
 
-SOURCE=".\freeglut-1.3\freeglutdll.def"
+SOURCE=".\src\freeglutdll.def"
 # End Source File
 # End Target
 # End Project
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..450880c
--- /dev/null
@@ -0,0 +1,42 @@
+## Process this file with automake to produce Makefile.im
+
+#
+# The library we want to build
+#
+lib_LTLIBRARIES = libfreeglut-1.3.la
+
+#
+# Those source files build the freeglut library
+#
+libfreeglut_1_3_la_SOURCES = freeglut_callbacks.c \
+                            freeglut_cursor.c \
+                            freeglut_display.c \
+                            freeglut_ext.c \
+                            freeglut_font.c \
+                            freeglut_font_data.c \
+                            freeglut_stroke_roman.c \
+                            freeglut_stroke_mono_roman.c \
+                            freeglut_gamemode.c \
+                            freeglut_geometry.c \
+                            freeglut_init.c \
+                            freeglut_joystick.c \
+                            freeglut_main.c \
+                            freeglut_menu.c \
+                            freeglut_misc.c \
+                            freeglut_overlay.c \
+                            freeglut_state.c \
+                            freeglut_structure.c \
+                            freeglut_teapot.c \
+                            freeglut_videoresize.c \
+                            freeglut_window.c
+
+
+#
+# Additional linker flags
+#       
+libfreeglut_1_3_la_LIBADD = $(LIBM) $(X_LIBS) -lGL -lGLU -lXext -lX11 -lXxf86vm
+libfreeglut_1_3_la_LDFLAGS = -version-info 0:0:0
+
+#
+# End of file
+#
diff --git a/src/freeglut_callbacks.c b/src/freeglut_callbacks.c
new file mode 100644 (file)
index 0000000..b741a0c
--- /dev/null
@@ -0,0 +1,333 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-callbacks"
+
+#include "../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) if( fgStructure.Window == NULL ) return;\
+                            fgStructure.Window->Callbacks.a = callback;
+
+/*
+ * Sets the Display callback for the current window
+ */
+void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) )
+{
+    SET_CALLBACK( Display );
+}
+
+/*
+ * Sets the Reshape callback for the current window
+ */
+void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) )
+{
+    SET_CALLBACK( Reshape );
+}
+
+/*
+ * Sets the Keyboard callback for the current window
+ */
+void FGAPIENTRY glutKeyboardFunc( void (* callback)( unsigned char, int, int ) )
+{
+    SET_CALLBACK( Keyboard );
+}
+
+/*
+ * Sets the Special callback for the current window
+ */
+void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) )
+{
+    SET_CALLBACK( Special );
+}
+
+/*
+ * Sets the global idle callback
+ */
+void FGAPIENTRY glutIdleFunc( void (* callback)( void ) )
+{
+    freeglut_assert_ready;
+
+    /*
+     * The global idle callback pointer is stored in fgState structure
+     */
+    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;
+
+    freeglut_assert_ready;
+
+    /*
+     * Create a new freeglut timer hook structure
+     */
+    timer = calloc( sizeof(SFG_Timer), 1 );
+
+    /*
+     * Remember the callback address and timer hook's ID
+     */
+    timer->Callback  = callback;
+    timer->ID        = timerID;
+
+    /*
+     * When will the time out happen (in terms of window's timer)
+     */
+    timer->TriggerTime = fgElapsedTime() + timeOut;
+
+    /*
+     * Have the new hook attached to the current window
+     */
+    fgListAppend( &fgState.Timers, &timer->Node );
+}
+
+/*
+ * Sets the Visibility callback for the current window.
+ *
+ * I had to peer to GLUT sources to clean up the mess.
+ * Can anyone please explain me what is going on here?!?
+ */
+static void fghVisibility( int status )
+{
+    freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Window != NULL );
+    freeglut_return_if_fail( fgStructure.Window->Callbacks.Visibility != NULL );
+
+    if( status == GLUT_HIDDEN  || status == GLUT_FULLY_COVERED )
+        fgStructure.Window->Callbacks.Visibility( GLUT_NOT_VISIBLE );
+    else
+        fgStructure.Window->Callbacks.Visibility( GLUT_VISIBLE );
+}
+
+void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) )
+{
+    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 ) )
+{
+    SET_CALLBACK( KeyboardUp );
+}
+
+/*
+ * Sets the special key release callback for the current window
+ */
+void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) )
+{
+    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 )
+{
+    SET_CALLBACK( Joystick );
+
+    freeglut_return_if_fail( fgStructure.Window != NULL );
+
+    /*
+     * Do not forget setting the joystick poll rate
+     */
+    fgStructure.Window->State.JoystickPollRate = pollInterval;
+
+    /*
+     * Make sure the joystick polling routine gets called as early as possible:
+     */
+    fgStructure.Window->State.JoystickLastPoll =
+        fgElapsedTime() - fgStructure.Window->State.JoystickPollRate;
+
+    if( fgStructure.Window->State.JoystickLastPoll < 0 )
+        fgStructure.Window->State.JoystickLastPoll = 0;
+}
+
+/*
+ * Sets the mouse callback for the current window
+ */
+void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) )
+{
+    SET_CALLBACK( Mouse );
+}
+
+/*
+ * Sets the mouse motion callback for the current window (one or more buttons are pressed)
+ */
+void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) )
+{
+    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 ) )
+{
+    SET_CALLBACK( Passive );
+}
+
+/*
+ * Window mouse entry/leave callback
+ */
+void FGAPIENTRY glutEntryFunc( void (* callback)( int ) )
+{
+    SET_CALLBACK( Entry );
+}
+
+/*
+ * Window destruction callbacks
+ */
+void FGAPIENTRY glutCloseFunc( void (* callback)( void ) )
+{
+    SET_CALLBACK( Destroy );
+}
+
+void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) )
+{
+    glutCloseFunc( callback );
+}
+
+/* A. Donev: Destruction callback for menus */
+void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) )
+{
+   if( fgStructure.Menu == NULL ) return;
+   fgStructure.Menu->Destroy = callback;
+}
+
+/*
+ * Deprecated version of glutMenuStatusFunc callback setting method
+ */
+void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) )
+{
+    freeglut_assert_ready;
+
+    fgState.MenuStateCallback = callback;
+}
+
+/*
+ * Sets the global menu status callback for the current window
+ */
+void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) )
+{
+    freeglut_assert_ready;
+
+    fgState.MenuStatusCallback = callback;
+}
+
+/*
+ * Sets the overlay display callback for the current window
+ */
+void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) )
+{
+    SET_CALLBACK( OverlayDisplay );
+}
+
+/*
+ * Sets the window status callback for the current window
+ */
+void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) )
+{
+    SET_CALLBACK( WindowStatus );
+}
+
+/*
+ * Sets the spaceball motion callback for the current window
+ */
+void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) )
+{
+    SET_CALLBACK( SpaceMotion );
+}
+
+/*
+ * Sets the spaceball rotate callback for the current window
+ */
+void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) )
+{
+    SET_CALLBACK( SpaceRotation );
+}
+
+/*
+ * Sets the spaceball button callback for the current window
+ */
+void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) )
+{
+    SET_CALLBACK( SpaceButton );
+}
+
+/*
+ * Sets the button box callback for the current window
+ */
+void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) )
+{
+    SET_CALLBACK( ButtonBox );
+}
+
+/*
+ * Sets the dials box callback for the current window
+ */
+void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) )
+{
+    SET_CALLBACK( Dials );
+}
+
+/*
+ * Sets the tablet motion callback for the current window
+ */
+void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) )
+{
+    SET_CALLBACK( TabletMotion );
+}
+
+/*
+ * Sets the tablet buttons callback for the current window
+ */
+void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) )
+{
+    SET_CALLBACK( TabletButton );
+}
+
+/*** END OF FILE ***/
diff --git a/src/freeglut_cursor.c b/src/freeglut_cursor.c
new file mode 100644 (file)
index 0000000..9d519c0
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-cursor"
+
+#include "../include/GL/freeglut.h"
+#include "freeglut_internal.h"
+
+#if TARGET_HOST_UNIX_X11
+    #include <X11/cursorfont.h>
+#endif
+
+/*
+ * TODO BEFORE THE STABLE RELEASE:
+ *
+ *  fgDisplayCursor()   -- this waits for better times
+ *  glutSetCursor()     -- both X and 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.
+ */
+
+/* -- INTERNAL FUNCTIONS --------------------------------------------------- */
+
+/*
+ * Display the mouse cursor using OpenGL calls
+ */
+void fgDisplayCursor( void )
+{
+    /*
+     * Do nothing for the moment
+     */
+}
+
+
+/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
+
+/*
+ * Set the cursor image to be used for the current window
+ */
+void FGAPIENTRY glutSetCursor( int cursorID )
+{
+    /*
+     * Make sure freeglut is ready and there is a current window set
+     */
+    freeglut_assert_ready; freeglut_assert_window;
+
+#if TARGET_HOST_UNIX_X11
+       {
+               Cursor cursor;
+
+           /*
+                * For now we'll limit ourselves to the X cursor fonts...
+                */
+#              define MAP_CURSOR(a,b) case a: cursor = XCreateFontCursor( fgDisplay.Display, b ); break;
+
+               switch( cursorID )
+               {
+                       MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, XC_left_ptr        );
+                       MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW,  XC_right_ptr       );
+                       MAP_CURSOR( GLUT_CURSOR_INFO,        XC_question_arrow  );
+                       MAP_CURSOR( GLUT_CURSOR_DESTROY,     XC_target          );
+                       MAP_CURSOR( GLUT_CURSOR_HELP,        XC_question_arrow  );
+                       MAP_CURSOR( GLUT_CURSOR_CYCLE,       XC_circle          );
+                       MAP_CURSOR( GLUT_CURSOR_SPRAY,       XC_spraycan        );
+                       MAP_CURSOR( GLUT_CURSOR_WAIT,        XC_watch           );
+                       MAP_CURSOR( GLUT_CURSOR_TEXT,        XC_draft_large     );
+                       MAP_CURSOR( GLUT_CURSOR_CROSSHAIR,   XC_crosshair       );
+                       MAP_CURSOR( GLUT_CURSOR_NONE,        XC_trek            );
+
+                       default:
+                       MAP_CURSOR( GLUT_CURSOR_UP_DOWN,     XC_arrow           );
+               }
+
+           /*
+            * Define a window's cursor now
+            */
+           XDefineCursor( fgDisplay.Display, fgStructure.Window->Window.Handle, cursor );
+       }
+
+#elif TARGET_HOST_WIN32
+       /*
+        * 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(fgStructure.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(fgStructure.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_UPARROW   );
+               MAP_CURSOR( GLUT_CURSOR_CROSSHAIR,   IDC_CROSS     );
+               /* MAP_CURSOR( GLUT_CURSOR_NONE,        IDC_NO             ); */
+               ZAP_CURSOR( GLUT_CURSOR_NONE,        NULL          );
+
+               default:
+               MAP_CURSOR( GLUT_CURSOR_UP_DOWN,     IDC_ARROW     );
+       }
+
+#endif
+
+    /*
+     * Remember the currently selected cursor
+     */
+    fgStructure.Window->State.Cursor = cursorID;
+}
+
+/*
+ * Moves the mouse pointer to given window coordinates
+ */
+void FGAPIENTRY glutWarpPointer( int x, int y )
+{
+    freeglut_assert_ready; freeglut_assert_window;
+
+#if TARGET_HOST_UNIX_X11
+    /*
+     * Move the mouse pointer to given window coordinates
+     */
+    XWarpPointer(
+        fgDisplay.Display,
+        None,
+        fgStructure.Window->Window.Handle,
+        0, 0, 0, 0,
+        x, y
+    );
+
+    XFlush( fgDisplay.Display );
+
+#elif TARGET_HOST_WIN32
+    {
+        POINT coords = { x, y };
+
+        /*
+         * First of all, we need to find the new screen-relative coordinates of the mouse cursor
+         */
+        ClientToScreen( fgStructure.Window->Window.Handle, &coords );
+
+        /*
+         * Now set the new mouse cursor position...
+         */
+        SetCursorPos( coords.x, coords.y );
+    }
+
+#endif
+}
+
+/*** END OF FILE ***/
diff --git a/src/freeglut_display.c b/src/freeglut_display.c
new file mode 100644 (file)
index 0000000..de19841
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-display"
+
+#include "../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 )
+{
+    /*
+     * Is there a current window set?
+     */
+    freeglut_assert_ready; freeglut_assert_window;
+
+    /*
+     * Just mark the window as one that we need to redisplay...
+     */
+    fgStructure.Window->State.Redisplay = TRUE;
+}
+
+/*
+ * Swaps the buffers for the current window (if any)
+ */
+void FGAPIENTRY glutSwapBuffers( void )
+{
+    /*
+     * As long as we've got a current window set...
+     */
+    freeglut_assert_ready; freeglut_assert_window;
+
+    /*
+     * Have the mouse cursor and/or the menus drawn for the current window
+     */
+    fgDisplayMenu();
+    fgDisplayCursor();
+
+    /*
+     * Make sure the current context is flushed
+     */
+    glFlush();
+
+    /*
+     * If it's single-buffered, we shouldn't be here.
+     */
+    if ( ! fgStructure.Window->Window.DoubleBuffered ) return ;
+
+#if TARGET_HOST_UNIX_X11
+    /*
+     * Issue the glXSwapBuffers call and be done with it
+     */
+    glXSwapBuffers( fgDisplay.Display, fgStructure.Window->Window.Handle );
+
+#elif TARGET_HOST_WIN32
+    /*
+     * Swap the window's buffers
+     */
+    SwapBuffers( fgStructure.Window->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_assert_ready;
+
+    /*
+     * Try looking for the window
+     */
+    window = fgWindowByID( windowID );
+
+    /*
+     * If failed, return
+     */
+    freeglut_return_if_fail( window != NULL );
+
+    /*
+     * Otherwise mark the window for being redisplayed
+     */
+    window->State.Redisplay = TRUE;
+}
+
+/*** END OF FILE ***/
diff --git a/src/freeglut_ext.c b/src/freeglut_ext.c
new file mode 100644 (file)
index 0000000..f6a5dad
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-ext"
+
+#include "../include/GL/freeglut.h"
+#include "freeglut_internal.h"
+
+
+struct name_address_pair {
+   const char *name;
+   void *address;
+};
+
+static struct name_address_pair glut_functions[] = {
+   { "glutInit", (void *) glutInit },
+   { "glutInitDisplayMode", (void *) glutInitDisplayMode },
+   { "glutInitDisplayString", (void *) glutInitDisplayString },
+   { "glutInitWindowPosition", (void *) glutInitWindowPosition },
+   { "glutInitWindowSize", (void *) glutInitWindowSize },
+   { "glutMainLoop", (void *) glutMainLoop },
+   { "glutCreateWindow", (void *) glutCreateWindow },
+   { "glutCreateSubWindow", (void *) glutCreateSubWindow },
+   { "glutDestroyWindow", (void *) glutDestroyWindow },
+   { "glutPostRedisplay", (void *) glutPostRedisplay },
+   { "glutPostWindowRedisplay", (void *) glutPostWindowRedisplay },
+   { "glutSwapBuffers", (void *) glutSwapBuffers },
+   { "glutGetWindow", (void *) glutGetWindow },
+   { "glutSetWindow", (void *) glutSetWindow },
+   { "glutSetWindowTitle", (void *) glutSetWindowTitle },
+   { "glutSetIconTitle", (void *) glutSetIconTitle },
+   { "glutPositionWindow", (void *) glutPositionWindow },
+   { "glutReshapeWindow", (void *) glutReshapeWindow },
+   { "glutPopWindow", (void *) glutPopWindow },
+   { "glutPushWindow", (void *) glutPushWindow },
+   { "glutIconifyWindow", (void *) glutIconifyWindow },
+   { "glutShowWindow", (void *) glutShowWindow },
+   { "glutHideWindow", (void *) glutHideWindow },
+   { "glutFullScreen", (void *) glutFullScreen },
+   { "glutSetCursor", (void *) glutSetCursor },
+   { "glutWarpPointer", (void *) glutWarpPointer },
+   { "glutEstablishOverlay", (void *) glutEstablishOverlay },
+   { "glutRemoveOverlay", (void *) glutRemoveOverlay },
+   { "glutUseLayer", (void *) glutUseLayer },
+   { "glutPostOverlayRedisplay", (void *) glutPostOverlayRedisplay },
+   { "glutPostWindowOverlayRedisplay", (void *) glutPostWindowOverlayRedisplay },
+   { "glutShowOverlay", (void *) glutShowOverlay },
+   { "glutHideOverlay", (void *) glutHideOverlay },
+   { "glutCreateMenu", (void *) glutCreateMenu },
+   { "glutDestroyMenu", (void *) glutDestroyMenu },
+   { "glutGetMenu", (void *) glutGetMenu },
+   { "glutSetMenu", (void *) glutSetMenu },
+   { "glutAddMenuEntry", (void *) glutAddMenuEntry },
+   { "glutAddSubMenu", (void *) glutAddSubMenu },
+   { "glutChangeToMenuEntry", (void *) glutChangeToMenuEntry },
+   { "glutChangeToSubMenu", (void *) glutChangeToSubMenu },
+   { "glutRemoveMenuItem", (void *) glutRemoveMenuItem },
+   { "glutAttachMenu", (void *) glutAttachMenu },
+   { "glutDetachMenu", (void *) glutDetachMenu },
+   { "glutDisplayFunc", (void *) glutDisplayFunc },
+   { "glutReshapeFunc", (void *) glutReshapeFunc },
+   { "glutKeyboardFunc", (void *) glutKeyboardFunc },
+   { "glutMouseFunc", (void *) glutMouseFunc },
+   { "glutMotionFunc", (void *) glutMotionFunc },
+   { "glutPassiveMotionFunc", (void *) glutPassiveMotionFunc },
+   { "glutEntryFunc", (void *) glutEntryFunc },
+   { "glutVisibilityFunc", (void *) glutVisibilityFunc },
+   { "glutIdleFunc", (void *) glutIdleFunc },
+   { "glutTimerFunc", (void *) glutTimerFunc },
+   { "glutMenuStateFunc", (void *) glutMenuStateFunc },
+   { "glutSpecialFunc", (void *) glutSpecialFunc },
+   { "glutSpaceballMotionFunc", (void *) glutSpaceballMotionFunc },
+   { "glutSpaceballRotateFunc", (void *) glutSpaceballRotateFunc },
+   { "glutSpaceballButtonFunc", (void *) glutSpaceballButtonFunc },
+   { "glutButtonBoxFunc", (void *) glutButtonBoxFunc },
+   { "glutDialsFunc", (void *) glutDialsFunc },
+   { "glutTabletMotionFunc", (void *) glutTabletMotionFunc },
+   { "glutTabletButtonFunc", (void *) glutTabletButtonFunc },
+   { "glutMenuStatusFunc", (void *) glutMenuStatusFunc },
+   { "glutOverlayDisplayFunc", (void *) glutOverlayDisplayFunc },
+   { "glutWindowStatusFunc", (void *) glutWindowStatusFunc },
+   { "glutKeyboardUpFunc", (void *) glutKeyboardUpFunc },
+   { "glutSpecialUpFunc", (void *) glutSpecialUpFunc },
+   { "glutJoystickFunc", (void *) glutJoystickFunc },
+   { "glutSetColor", (void *) glutSetColor },
+   { "glutGetColor", (void *) glutGetColor },
+   { "glutCopyColormap", (void *) glutCopyColormap },
+   { "glutGet", (void *) glutGet },
+   { "glutDeviceGet", (void *) glutDeviceGet },
+   { "glutExtensionSupported", (void *) glutExtensionSupported },
+   { "glutGetModifiers", (void *) glutGetModifiers },
+   { "glutLayerGet", (void *) glutLayerGet },
+   { "glutBitmapCharacter", (void *) glutBitmapCharacter },
+   { "glutBitmapWidth", (void *) glutBitmapWidth },
+   { "glutStrokeCharacter", (void *) glutStrokeCharacter },
+   { "glutStrokeWidth", (void *) glutStrokeWidth },
+   { "glutBitmapLength", (void *) glutBitmapLength },
+   { "glutStrokeLength", (void *) glutStrokeLength },
+   { "glutWireSphere", (void *) glutWireSphere },
+   { "glutSolidSphere", (void *) glutSolidSphere },
+   { "glutWireCone", (void *) glutWireCone },
+   { "glutSolidCone", (void *) glutSolidCone },
+   { "glutWireCube", (void *) glutWireCube },
+   { "glutSolidCube", (void *) glutSolidCube },
+   { "glutWireTorus", (void *) glutWireTorus },
+   { "glutSolidTorus", (void *) glutSolidTorus },
+   { "glutWireDodecahedron", (void *) glutWireDodecahedron },
+   { "glutSolidDodecahedron", (void *) glutSolidDodecahedron },
+   { "glutWireTeapot", (void *) glutWireTeapot },
+   { "glutSolidTeapot", (void *) glutSolidTeapot },
+   { "glutWireOctahedron", (void *) glutWireOctahedron },
+   { "glutSolidOctahedron", (void *) glutSolidOctahedron },
+   { "glutWireTetrahedron", (void *) glutWireTetrahedron },
+   { "glutSolidTetrahedron", (void *) glutSolidTetrahedron },
+   { "glutWireIcosahedron", (void *) glutWireIcosahedron },
+   { "glutSolidIcosahedron", (void *) glutSolidIcosahedron },
+   { "glutVideoResizeGet", (void *) glutVideoResizeGet },
+   { "glutSetupVideoResizing", (void *) glutSetupVideoResizing },
+   { "glutStopVideoResizing", (void *) glutStopVideoResizing },
+   { "glutVideoResize", (void *) glutVideoResize },
+   { "glutVideoPan", (void *) glutVideoPan },
+   { "glutReportErrors", (void *) glutReportErrors },
+   { "glutIgnoreKeyRepeat", (void *) glutIgnoreKeyRepeat },
+   { "glutSetKeyRepeat", (void *) glutSetKeyRepeat },
+   { "glutForceJoystickFunc", (void *) glutForceJoystickFunc },
+   { "glutGameModeString", (void *) glutGameModeString },
+   { "glutEnterGameMode", (void *) glutEnterGameMode },
+   { "glutLeaveGameMode", (void *) glutLeaveGameMode },
+   { "glutGameModeGet", (void *) glutGameModeGet },
+   /* freeglut extensions */
+   { "glutMainLoopEvent", (void *) glutMainLoopEvent },
+   { "glutLeaveMainLoop", (void *) glutLeaveMainLoop },
+   { "glutCloseFunc", (void *) glutCloseFunc },
+   { "glutWMCloseFunc", (void *) glutWMCloseFunc },
+   { "glutMenuDestroyFunc", (void *) glutMenuDestroyFunc },
+   { "glutSetOption", (void *) glutSetOption },
+   { "glutSetWindowData", (void *) glutSetWindowData },
+   { "glutGetWindowData", (void *) glutGetWindowData },
+   { "glutSetMenuData", (void *) glutSetMenuData },
+   { "glutGetMenuData", (void *) glutGetMenuData },
+   { "glutBitmapHeight", (void *) glutBitmapHeight },
+   { "glutStrokeHeight", (void *) glutStrokeHeight },
+   { "glutBitmapString", (void *) glutBitmapString },
+   { "glutStrokeString", (void *) glutStrokeString },
+   { "glutWireRhombicDodecahedron", (void *) glutWireRhombicDodecahedron },
+   { "glutSolidRhombicDodecahedron", (void *) glutSolidRhombicDodecahedron },
+   { "glutWireSierpinskiSponge ", (void *) glutWireSierpinskiSponge },
+   { "glutSolidSierpinskiSponge ", (void *) glutSolidSierpinskiSponge },
+   { "glutGetProcAddress", (void *) glutGetProcAddress },
+   { NULL, NULL }
+};   
+
+
+void * FGAPIENTRY glutGetProcAddress(const char *procName)
+{
+   /* Try GLUT functions first */
+   int i;
+   for (i = 0; glut_functions[i].name; i++) {
+      if (strcmp(glut_functions[i].name, procName) == 0)
+         return glut_functions[i].address;
+   }
+
+   /* Try core GL functions */
+#if TARGET_HOST_WIN32
+  return (void *) wglGetProcAddress((LPCSTR) procName);
+#elif TARGET_HOST_UNIX_X11 && defined(GLX_ARB_get_proc_address)
+  return (void *) glXGetProcAddressARB((const GLubyte *) procName);
+#else
+  return NULL;
+#endif
+}
diff --git a/src/freeglut_font.c b/src/freeglut_font.c
new file mode 100644 (file)
index 0000000..46e2219
--- /dev/null
@@ -0,0 +1,480 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-font"
+
+#include "../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;
+
+/*
+ * This is for GLUT binary compatibility, as suggested by Steve Baker
+ */
+#if TARGET_HOST_UNIX_X11
+  void* glutStrokeRoman;
+  void* glutStrokeMonoRoman;
+  void* glutBitmap9By15;
+  void* glutBitmap8By13;
+  void* glutBitmapTimesRoman10;
+  void* glutBitmapTimesRoman24;
+  void* glutBitmapHelvetica10;
+  void* glutBitmapHelvetica12;
+  void* glutBitmapHelvetica18;
+#endif
+
+
+/* -- 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 )
+{
+  /*
+   * Try matching the font ID and the font data structure
+   */
+  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 );
+
+  /*
+   * This probably is the library user's fault
+   */
+  fgError( "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 )
+{
+  /*
+   * Try matching the font ID and the font data structure
+   */
+  if( font == GLUT_STROKE_ROMAN      ) return( &fgStrokeRoman     );
+  if( font == GLUT_STROKE_MONO_ROMAN ) return( &fgStrokeMonoRoman );
+
+  /*
+   * This probably is the library user's fault
+   */
+  fgError( "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;
+
+  /*
+   * First of all we'll need a font to use
+   */
+  SFG_Font* font = fghFontByID( fontID );
+
+  /*
+   * Make sure the character we want to output is valid
+   */
+  freeglut_return_if_fail( character >= 0 && character < 256 );
+
+  /*
+   * Then find the character we want to draw
+   */
+  face = font->Characters[ character - 1 ];
+
+  /*
+   * Save the old pixel store settings
+   */
+  glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
+
+  /*
+   * Set up the pixel unpacking ways
+   */
+  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        );
+
+  /*
+   * We'll use a glBitmap call to draw the font.
+   */
+  glBitmap(
+      face[ 0 ], font->Height,      /* The bitmap's width and height */
+      font->xorig, font->yorig,     /* The origin -- what on earth?  */
+      (float)(face[ 0 ]), 0.0,      /* The raster advance -- inc. x  */
+      (face + 1)                    /* The packed bitmap data...     */
+  );
+
+  /*
+   * Restore the old pixel store settings
+   */
+  glPopClientAttrib();
+}
+
+void FGAPIENTRY glutBitmapString( void* fontID, const char *string )
+{
+  int c;
+  int numchar = strlen ( string ) ;
+
+  /*
+   * First of all we'll need a font to use
+   */
+  SFG_Font* font = fghFontByID( fontID );
+
+  float raster_position[4] ;
+  glGetFloatv ( GL_CURRENT_RASTER_POSITION, raster_position ) ;
+
+  /*
+   * Save the old pixel store settings
+   */
+  glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
+
+  /*
+   * Set up the pixel unpacking ways
+   */
+  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 carriage return will simply translate the next character's insertion point back to the
+   * start of the line and down one line.
+   */
+  for( c = 0; c < numchar; c++ )
+  {
+    if ( string[c] == '\n' )
+    {
+      raster_position[1] -= (float)font->Height ;
+      glRasterPos4fv ( raster_position ) ;
+    }
+    else  /* Not a carriage return, draw the bitmap character */
+    {
+      const GLubyte* face = font->Characters[ string[ c ] - 1 ] ;
+
+      /*
+       * We'll use a glBitmap call to draw the font.
+       */
+      glBitmap(
+          face[ 0 ], font->Height,      /* The bitmap's width and height */
+          font->xorig, font->yorig,     /* The origin -- what on earth?  */
+          (float)(face[ 0 ]), 0.0,      /* The raster advance -- inc. x  */
+          (face + 1)                    /* The packed bitmap data...     */
+      ) ;
+    }
+  }
+
+  /*
+   * Restore the old pixel store settings
+   */
+  glPopClientAttrib();
+}
+
+/*
+ * Returns the width in pixels of a font's character
+ */
+int FGAPIENTRY glutBitmapWidth( void* fontID, int character )
+{
+  /*
+   * First of all, grab the font we need
+   */
+  SFG_Font* font = fghFontByID( fontID );
+
+  /*
+   * Make sure the character we want to output is valid
+   */
+  freeglut_return_val_if_fail( character > 0 && character < 256, 0 );
+
+  /*
+       * Scan the font looking for the specified character
+   */
+  return( *(font->Characters[ character - 1 ]) );
+}
+
+/*
+ * Return the width of a string drawn using a bitmap font
+ */
+int FGAPIENTRY glutBitmapLength( void* fontID, const char* string )
+{
+  int c, length = 0, this_line_length = 0;
+
+  /*
+   * First of all, grab the font we need
+   */
+  SFG_Font* font = fghFontByID( fontID );
+
+  /*
+   * Step through the characters in the string, adding up the width of each one
+   */
+  int numchar = strlen ( string ) ;
+  for( c = 0; c < numchar; c++ )
+  {
+    if ( string[ c ] == '\n' )  /* Carriage return, reset the length of this line */
+    {
+      if ( length < this_line_length ) length = this_line_length ;
+      this_line_length = 0 ;
+    }
+    else  /* Not a carriage return, increment the length of this line */
+      this_line_length += *(font->Characters[ string[ c ] - 1 ]) ;
+  }
+
+  if ( length < this_line_length ) length = this_line_length ;
+
+  /*
+   * Return the result now
+   */
+  return( length );
+}
+
+/*
+ * Returns the height of a bitmap font
+ */
+int FGAPIENTRY glutBitmapHeight( void* fontID )
+{
+  /*
+   * See which font are we queried about
+   */
+  SFG_Font* font = fghFontByID( fontID );
+
+  /*
+   * Return the character set's height
+   */
+  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;
+
+  /*
+   * First of all we'll need a font to use
+   */
+  SFG_StrokeFont* font = fghStrokeByID( fontID );
+
+  /*
+   * Make sure the character we want to output is valid
+   */
+  freeglut_return_if_fail( character >= 0 && character < font->Quantity );
+
+  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 char *string )
+{
+  int c, i, j;
+  int numchar = strlen ( string ) ;
+  float length = 0.0 ;
+
+  /*
+   * First of all we'll need a font to use
+   */
+  SFG_StrokeFont* font = fghStrokeByID( fontID );
+
+  /*
+   * Step through the string, drawing each character.
+   * A carriage return will simply translate the next character's insertion point back to the
+   * start of the line and down one line.
+   */
+  for( c = 0; c < numchar; c++ )
+  {
+    if ( ( string[ c ] >= 0 ) && ( string[ c ] < font->Quantity ) )
+    {
+      if ( string[c] == '\n' )
+      {
+        glTranslatef ( -length, -(float)(font->Height), 0.0 ) ;
+        length = 0.0 ;
+      }
+      else  /* Not a carriage return, draw the bitmap character */
+      {
+        const SFG_StrokeChar *schar = font->Characters[string[c]];
+        if ( schar != NULL )
+        {
+          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;
+  /*
+   * First of all we'll need a font to use
+   */
+  SFG_StrokeFont* font = fghStrokeByID( fontID );
+
+  /*
+   * Make sure the character we want to output is valid
+   */
+  freeglut_return_val_if_fail( character >= 0 && character < font->Quantity, 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 char* string )
+{
+  int c;
+  float length = 0.0;
+  float this_line_length = 0.0 ;
+
+  /*
+   * First of all we'll need a font to use
+   */
+  SFG_StrokeFont* font = fghStrokeByID( fontID );
+
+  /*
+   * Step through the characters in the string, adding up the width of each one
+   */
+  int numchar = strlen ( string ) ;
+  for( c = 0; c < numchar; c++ )
+  {
+    if ( ( string[ c ] >= 0 ) && ( string[ c ] < font->Quantity ) )
+    {
+      if ( string[ c ] == '\n' )  /* Carriage return, reset the length of this line */
+      {
+        if ( length < this_line_length ) length = this_line_length ;
+        this_line_length = 0.0 ;
+      }
+      else  /* Not a carriage return, increment the length of this line */
+      {
+        const SFG_StrokeChar *schar = font->Characters[string[c]];
+        if ( schar != NULL )
+          this_line_length += schar->Right ;
+      }
+    }
+  }
+
+  if ( length < this_line_length ) length = this_line_length ;
+
+  /*
+   * Return the result now
+   */
+  return( (int)(length+0.5) );
+}
+
+/*
+ * Returns the height of a stroke font
+ */
+GLfloat FGAPIENTRY glutStrokeHeight( void* fontID )
+{
+    /*
+     * See which font are we queried about
+     */
+    SFG_StrokeFont* font = fghStrokeByID( fontID );
+
+    /*
+     * Return the character set's height
+     */
+    return( font->Height );
+}
+
+/*** END OF FILE ***/
diff --git a/src/freeglut_font_data.c b/src/freeglut_font_data.c
new file mode 100644 (file)
index 0000000..c18a15e
--- /dev/null
@@ -0,0 +1,824 @@
+/*
+ * freeglut_font_data.c
+ *
+ * This file has been automatically generated by the genfonts utility.
+ *
+ * Copyright (c) 1999-2000 by Pawel W. Olszta
+ * Written by Pawel W. Olszta, <olszta@sourceforge.net>
+ *
+ * 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 Sotware.
+ *
+ * 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 HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "../include/GL/freeglut.h"
+#include "freeglut_internal.h"
+
+/*
+ * Following fonts are defined in this file:
+ * 
+ * 1. fgFontFixed8x13 <-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1>
+ * 2. fgFontFixed9x15 <-misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1>
+ * 3. fgFontHelvetica10 <-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1>
+ * 4. fgFontHelvetica12 <-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1>
+ * 5. fgFontHelvetica18 <-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1>
+ * 6. fgFontTimesRoman10 <-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1>
+ * 7. fgFontTimesRoman24 <-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1>
+ */
+
+static const GLubyte Fixed8x13_Character_032[] = {  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* blank */
+static const GLubyte Fixed8x13_Character_097[] = {  8,  0,  0,116,140,132,124,  4,120,  0,  0,  0,  0,  0}; /* "a" */
+static const GLubyte Fixed8x13_Character_098[] = {  8,  0,  0,184,196,132,132,196,184,128,128,128,  0,  0};
+static const GLubyte Fixed8x13_Character_099[] = {  8,  0,  0,120,132,128,128,132,120,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_100[] = {  8,  0,  0,116,140,132,132,140,116,  4,  4,  4,  0,  0};
+static const GLubyte Fixed8x13_Character_101[] = {  8,  0,  0,120,132,128,252,132,120,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_102[] = {  8,  0,  0, 64, 64, 64, 64,248, 64, 64, 68, 56,  0,  0};
+static const GLubyte Fixed8x13_Character_103[] = {  8,120,132,120,128,112,136,136,116,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_104[] = {  8,  0,  0,132,132,132,132,196,184,128,128,128,  0,  0};
+static const GLubyte Fixed8x13_Character_105[] = {  8,  0,  0,248, 32, 32, 32, 32, 96,  0, 32,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_106[] = {  8,112,136,136,  8,  8,  8,  8, 24,  0,  8,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_107[] = {  8,  0,  0,132,136,144,224,144,136,128,128,128,  0,  0};
+static const GLubyte Fixed8x13_Character_108[] = {  8,  0,  0,248, 32, 32, 32, 32, 32, 32, 32, 96,  0,  0};
+static const GLubyte Fixed8x13_Character_109[] = {  8,  0,  0,130,146,146,146,146,236,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_110[] = {  8,  0,  0,132,132,132,132,196,184,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_111[] = {  8,  0,  0,120,132,132,132,132,120,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_112[] = {  8,128,128,128,184,196,132,196,184,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_113[] = {  8,  4,  4,  4,116,140,132,140,116,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_114[] = {  8,  0,  0, 64, 64, 64, 64, 68,184,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_115[] = {  8,  0,  0,120,132, 24, 96,132,120,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_116[] = {  8,  0,  0, 56, 68, 64, 64, 64,248, 64, 64,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_117[] = {  8,  0,  0,116,136,136,136,136,136,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_119[] = {  8,  0,  0, 68,170,146,146,130,130,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_118[] = {  8,  0,  0, 32, 80, 80,136,136,136,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_120[] = {  8,  0,  0,132, 72, 48, 48, 72,132,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_121[] = {  8,120,132,  4,116,140,132,132,132,  0,  0,  0,  0,  0};
+static const GLubyte Fixed8x13_Character_122[] = {  8,  0,  0,252, 64, 32, 16,  8,252,  0,  0,  0,  0,  0}; /* "z" */
+static const GLubyte Fixed8x13_Character_065[] = {  8,  0,  0,132,132,132,252,132,132,132, 72, 48,  0,  0}; /* "A" */
+static const GLubyte Fixed8x13_Character_066[] = {  8,  0,  0,252, 66, 66, 66,124, 66, 66, 66,252,  0,  0};
+static const GLubyte Fixed8x13_Character_067[] = {  8,  0,  0,120,132,128,128,128,128,128,132,120,  0,  0};
+static const GLubyte Fixed8x13_Character_068[] = {  8,  0,  0,252, 66, 66, 66, 66, 66, 66, 66,252,  0,  0};
+static const GLubyte Fixed8x13_Character_069[] = {  8,  0,  0,252,128,128,128,240,128,128,128,252,  0,  0};
+static const GLubyte Fixed8x13_Character_070[] = {  8,  0,  0,128,128,128,128,240,128,128,128,252,  0,  0};
+static const GLubyte Fixed8x13_Character_071[] = {  8,  0,  0,116,140,132,156,128,128,128,132,120,  0,  0};
+static const GLubyte Fixed8x13_Character_072[] = {  8,  0,  0,132,132,132,132,252,132,132,132,132,  0,  0};
+static const GLubyte Fixed8x13_Character_073[] = {  8,  0,  0,248, 32, 32, 32, 32, 32, 32, 32,248,  0,  0};
+static const GLubyte Fixed8x13_Character_074[] = {  8,  0,  0,112,136,  8,  8,  8,  8,  8,  8, 60,  0,  0};
+static const GLubyte Fixed8x13_Character_075[] = {  8,  0,  0,132,136,144,160,192,160,144,136,132,  0,  0};
+static const GLubyte Fixed8x13_Character_076[] = {  8,  0,  0,252,128,128,128,128,128,128,128,128,  0,  0};
+static const GLubyte Fixed8x13_Character_077[] = {  8,  0,  0,130,130,130,146,146,170,198,130,130,  0,  0};
+static const GLubyte Fixed8x13_Character_078[] = {  8,  0,  0,132,132,132,140,148,164,196,132,132,  0,  0};
+static const GLubyte Fixed8x13_Character_079[] = {  8,  0,  0,120,132,132,132,132,132,132,132,120,  0,  0};
+static const GLubyte Fixed8x13_Character_080[] = {  8,  0,  0,128,128,128,128,248,132,132,132,248,  0,  0};
+static const GLubyte Fixed8x13_Character_081[] = {  8,  0,  4,120,148,164,132,132,132,132,132,120,  0,  0};
+static const GLubyte Fixed8x13_Character_082[] = {  8,  0,  0,132,136,144,160,248,132,132,132,248,  0,  0};
+static const GLubyte Fixed8x13_Character_083[] = {  8,  0,  0,120,132,  4,  4,120,128,128,132,120,  0,  0};
+static const GLubyte Fixed8x13_Character_084[] = {  8,  0,  0, 16, 16, 16, 16, 16, 16, 16, 16,254,  0,  0};
+static const GLubyte Fixed8x13_Character_085[] = {  8,  0,  0,120,132,132,132,132,132,132,132,132,  0,  0};
+static const GLubyte Fixed8x13_Character_087[] = {  8,  0,  0, 68,170,146,146,146,130,130,130,130,  0,  0};
+static const GLubyte Fixed8x13_Character_086[] = {  8,  0,  0, 16, 40, 40, 40, 68, 68, 68,130,130,  0,  0};
+static const GLubyte Fixed8x13_Character_088[] = {  8,  0,  0,130,130, 68, 40, 16, 40, 68,130,130,  0,  0};
+static const GLubyte Fixed8x13_Character_089[] = {  8,  0,  0, 16, 16, 16, 16, 16, 40, 68,130,130,  0,  0};
+static const GLubyte Fixed8x13_Character_090[] = {  8,  0,  0,252,128,128, 64, 32, 16,  8,  4,252,  0,  0}; /* "Z" */
+static const GLubyte Fixed8x13_Character_048[] = {  8,  0,  0, 48, 72,132,132,132,132,132, 72, 48,  0,  0}; /* "0" */
+static const GLubyte Fixed8x13_Character_049[] = {  8,  0,  0,248, 32, 32, 32, 32, 32,160, 96, 32,  0,  0};
+static const GLubyte Fixed8x13_Character_050[] = {  8,  0,  0,252,128, 64, 48,  8,  4,132,132,120,  0,  0};
+static const GLubyte Fixed8x13_Character_051[] = {  8,  0,  0,120,132,  4,  4, 56, 16,  8,  4,252,  0,  0};
+static const GLubyte Fixed8x13_Character_052[] = {  8,  0,  0,  8,  8,252,136,136, 72, 40, 24,  8,  0,  0};
+static const GLubyte Fixed8x13_Character_053[] = {  8,  0,  0,120,132,  4,  4,196,184,128,128,252,  0,  0};
+static const GLubyte Fixed8x13_Character_054[] = {  8,  0,  0,120,132,132,196,184,128,128, 64, 56,  0,  0};
+static const GLubyte Fixed8x13_Character_055[] = {  8,  0,  0, 64, 64, 32, 32, 16, 16,  8,  4,252,  0,  0};
+static const GLubyte Fixed8x13_Character_056[] = {  8,  0,  0,120,132,132,132,120,132,132,132,120,  0,  0};
+static const GLubyte Fixed8x13_Character_057[] = {  8,  0,  0,112,  8,  4,  4,116,140,132,132,120,  0,  0}; /* "9" */
+static const GLubyte Fixed8x13_Character_096[] = {  8,  0,  0,  0,  0,  0,  0,  0,  0, 16, 96,224,  0,  0}; /* "`" */
+static const GLubyte Fixed8x13_Character_126[] = {  8,  0,  0,  0,  0,  0,  0,  0,  0,144,168, 72,  0,  0}; /* "~" */
+static const GLubyte Fixed8x13_Character_033[] = {  8,  0,  0,128,  0,128,128,128,128,128,128,128,  0,  0}; /* "!" */
+static const GLubyte Fixed8x13_Character_064[] = {  8,  0,  0,120,128,148,172,164,156,132,132,120,  0,  0}; /* "@" */
+static const GLubyte Fixed8x13_Character_035[] = {  8,  0,  0,  0, 72, 72,252, 72,252, 72, 72,  0,  0,  0}; /* "#" */
+static const GLubyte Fixed8x13_Character_036[] = {  8,  0,  0,  0, 32,240, 40,112,160,120, 32,  0,  0,  0}; /* "$" */
+static const GLubyte Fixed8x13_Character_037[] = {  8,  0,  0,136, 84, 72, 32, 16, 16, 72,164, 68,  0,  0}; /* "%" */
+static const GLubyte Fixed8x13_Character_094[] = {  8,  0,  0,  0,  0,  0,  0,  0,  0,136, 80, 32,  0,  0}; /* "^" */
+static const GLubyte Fixed8x13_Character_038[] = {  8,  0,  0,116,136,148, 96,144,144, 96,  0,  0,  0,  0}; /* "&" */
+static const GLubyte Fixed8x13_Character_042[] = {  8,  0,  0,  0,  0, 72, 48,252, 48, 72,  0,  0,  0,  0}; /* "*" */
+static const GLubyte Fixed8x13_Character_040[] = {  8,  0,  0, 32, 64, 64,128,128,128, 64, 64, 32,  0,  0}; /* "(" */
+static const GLubyte Fixed8x13_Character_041[] = {  8,  0,  0,128, 64, 64, 32, 32, 32, 64, 64,128,  0,  0}; /* ")" */
+static const GLubyte Fixed8x13_Character_045[] = {  8,  0,  0,  0,  0,  0,  0,252,  0,  0,  0,  0,  0,  0}; /* "-" */
+static const GLubyte Fixed8x13_Character_095[] = {  8,  0,254,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "_" */
+static const GLubyte Fixed8x13_Character_061[] = {  8,  0,  0,  0,  0,252,  0,  0,252,  0,  0,  0,  0,  0}; /* "=" */
+static const GLubyte Fixed8x13_Character_043[] = {  8,  0,  0,  0,  0, 32, 32,248, 32, 32,  0,  0,  0,  0}; /* "+" */
+static const GLubyte Fixed8x13_Character_091[] = {  8,  0,  0,240,128,128,128,128,128,128,128,240,  0,  0}; /* "[" */
+static const GLubyte Fixed8x13_Character_123[] = {  8,  0,  0, 56, 64, 64, 32,192, 32, 64, 64, 56,  0,  0}; /* "{" */
+static const GLubyte Fixed8x13_Character_125[] = {  8,  0,  0,224, 16, 16, 32, 24, 32, 16, 16,224,  0,  0}; /* "}" */
+static const GLubyte Fixed8x13_Character_093[] = {  8,  0,  0,240, 16, 16, 16, 16, 16, 16, 16,240,  0,  0}; /* "]" */
+static const GLubyte Fixed8x13_Character_059[] = {  8,  0,128, 96,112,  0,  0, 32,112, 32,  0,  0,  0,  0}; /* ";" */
+static const GLubyte Fixed8x13_Character_058[] = {  8,  0, 64,224, 64,  0,  0, 64,224, 64,  0,  0,  0,  0}; /* ":" */
+static const GLubyte Fixed8x13_Character_044[] = {  8,  0,128, 96,112,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "," */
+static const GLubyte Fixed8x13_Character_046[] = {  8,  0, 64,224, 64,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "." */
+static const GLubyte Fixed8x13_Character_060[] = {  8,  0,  0,  8, 16, 32, 64,128, 64, 32, 16,  8,  0,  0}; /* "<" */
+static const GLubyte Fixed8x13_Character_062[] = {  8,  0,  0,128, 64, 32, 16,  8, 16, 32, 64,128,  0,  0}; /* ">" */
+static const GLubyte Fixed8x13_Character_047[] = {  8,  0,  0,128,128, 64, 32, 16,  8,  4,  2,  2,  0,  0}; /* "/" */
+static const GLubyte Fixed8x13_Character_063[] = {  8,  0,  0, 16,  0, 16, 16,  8,  4,132,132,120,  0,  0}; /* "?" */
+static const GLubyte Fixed8x13_Character_092[] = {  8,  0,  0,  2,  2,  4,  8, 16, 32, 64,128,128,  0,  0}; /* "\" */
+static const GLubyte Fixed8x13_Character_034[] = {  8,  0,  0,  0,  0,  0,  0,  0,  0,144,144,144,  0,  0}; /* """ */
+
+/* Missing Characters filled in by John Fay by hand ... */
+static const GLubyte Fixed8x13_Character_039[] = {  8,  0,  0,  0,  0,  0,  0,  0,  0, 32, 32, 32,  0,  0}; /* """ */
+static const GLubyte Fixed8x13_Character_124[] = {  8, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,  0,  0}; /* """ */
+
+
+/* The font characters mapping: */
+static const GLubyte* Fixed8x13_Character_Map[] = {Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_032,Fixed8x13_Character_033,Fixed8x13_Character_034,Fixed8x13_Character_035,Fixed8x13_Character_036,Fixed8x13_Character_037,Fixed8x13_Character_038,Fixed8x13_Character_039,Fixed8x13_Character_040,
+   Fixed8x13_Character_041,Fixed8x13_Character_042,Fixed8x13_Character_043,Fixed8x13_Character_044,Fixed8x13_Character_045,Fixed8x13_Character_046,Fixed8x13_Character_047,Fixed8x13_Character_048,Fixed8x13_Character_049,Fixed8x13_Character_050,Fixed8x13_Character_051,Fixed8x13_Character_052,Fixed8x13_Character_053,Fixed8x13_Character_054,Fixed8x13_Character_055,Fixed8x13_Character_056,Fixed8x13_Character_057,Fixed8x13_Character_058,Fixed8x13_Character_059,Fixed8x13_Character_060,Fixed8x13_Character_061,Fixed8x13_Character_062,Fixed8x13_Character_063,Fixed8x13_Character_064,Fixed8x13_Character_065,Fixed8x13_Character_066,Fixed8x13_Character_067,Fixed8x13_Character_068,Fixed8x13_Character_069,Fixed8x13_Character_070,Fixed8x13_Character_071,Fixed8x13_Character_072,Fixed8x13_Character_073,Fixed8x13_Character_074,Fixed8x13_Character_075,Fixed8x13_Character_076,Fixed8x13_Character_077,Fixed8x13_Character_078,Fixed8x13_Character_079,Fixed8x13_Character_080,Fixed8x13_Character_081,Fixed8x13_Character_082,
+   Fixed8x13_Character_083,Fixed8x13_Character_084,Fixed8x13_Character_085,Fixed8x13_Character_086,Fixed8x13_Character_087,Fixed8x13_Character_088,Fixed8x13_Character_089,Fixed8x13_Character_090,Fixed8x13_Character_091,Fixed8x13_Character_092,Fixed8x13_Character_093,Fixed8x13_Character_094,Fixed8x13_Character_095,Fixed8x13_Character_096,Fixed8x13_Character_097,Fixed8x13_Character_098,Fixed8x13_Character_099,Fixed8x13_Character_100,Fixed8x13_Character_101,Fixed8x13_Character_102,Fixed8x13_Character_103,Fixed8x13_Character_104,Fixed8x13_Character_105,Fixed8x13_Character_106,Fixed8x13_Character_107,Fixed8x13_Character_108,Fixed8x13_Character_109,Fixed8x13_Character_110,Fixed8x13_Character_111,Fixed8x13_Character_112,Fixed8x13_Character_113,Fixed8x13_Character_114,Fixed8x13_Character_115,Fixed8x13_Character_116,Fixed8x13_Character_117,Fixed8x13_Character_118,Fixed8x13_Character_119,Fixed8x13_Character_120,Fixed8x13_Character_121,Fixed8x13_Character_122,Fixed8x13_Character_123,Fixed8x13_Character_124,
+   Fixed8x13_Character_125,Fixed8x13_Character_126,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,
+   Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,
+   Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,
+   Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,Fixed8x13_Character_042,NULL};
+
+/* The font structure: */
+const SFG_Font fgFontFixed8x13 = { "-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1", 93, 13, Fixed8x13_Character_Map, -1.0f, 2.0f };
+
+static const GLubyte Fixed9x15_Character_032[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* blank */
+static const GLubyte Fixed9x15_Character_097[] = {  9,  0,  0,  0,  0,  0,  0,122,  0,134,  0,130,  0,126,  0,  2,  0,  2,  0,124,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "a" */
+static const GLubyte Fixed9x15_Character_098[] = {  9,  0,  0,  0,  0,  0,  0,188,  0,194,  0,130,  0,130,  0,130,  0,194,  0,188,  0,128,  0,128,  0,128,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_099[] = {  9,  0,  0,  0,  0,  0,  0,124,  0,130,  0,128,  0,128,  0,128,  0,130,  0,124,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_100[] = {  9,  0,  0,  0,  0,  0,  0,122,  0,134,  0,130,  0,130,  0,130,  0,134,  0,122,  0,  2,  0,  2,  0,  2,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_101[] = {  9,  0,  0,  0,  0,  0,  0,124,  0,128,  0,128,  0,254,  0,130,  0,130,  0,124,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_102[] = {  9,  0,  0,  0,  0,  0,  0, 32,  0, 32,  0, 32,  0, 32,  0,248,  0, 32,  0, 32,  0, 34,  0, 34,  0, 28,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_103[] = {  9,124,  0,130,  0,130,  0,124,  0,128,  0,120,  0,132,  0,132,  0,132,  0,122,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_104[] = {  9,  0,  0,  0,  0,  0,  0,130,  0,130,  0,130,  0,130,  0,130,  0,194,  0,188,  0,128,  0,128,  0,128,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_105[] = {  9,  0,  0,  0,  0,  0,  0,248,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0,224,  0,  0,  0,  0,  0, 96,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_106[] = {  9,120,  0,132,  0,132,  0,132,  0,  4,  0,  4,  0,  4,  0,  4,  0,  4,  0, 28,  0,  0,  0,  0,  0, 12,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_107[] = {  9,  0,  0,  0,  0,  0,  0,130,  0,140,  0,176,  0,192,  0,176,  0,140,  0,130,  0,128,  0,128,  0,128,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_108[] = {  9,  0,  0,  0,  0,  0,  0,248,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0,224,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_109[] = {  9,  0,  0,  0,  0,  0,  0,130,  0,146,  0,146,  0,146,  0,146,  0,146,  0,236,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_110[] = {  9,  0,  0,  0,  0,  0,  0,130,  0,130,  0,130,  0,130,  0,130,  0,194,  0,188,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_111[] = {  9,  0,  0,  0,  0,  0,  0,124,  0,130,  0,130,  0,130,  0,130,  0,130,  0,124,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_112[] = {  9,128,  0,128,  0,128,  0,188,  0,194,  0,130,  0,130,  0,130,  0,194,  0,188,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_113[] = {  9,  2,  0,  2,  0,  2,  0,122,  0,134,  0,130,  0,130,  0,130,  0,134,  0,122,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_114[] = {  9,  0,  0,  0,  0,  0,  0, 64,  0, 64,  0, 64,  0, 64,  0, 66,  0, 98,  0,156,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_115[] = {  9,  0,  0,  0,  0,  0,  0,124,  0,130,  0,  2,  0,124,  0,128,  0,130,  0,124,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_116[] = {  9,  0,  0,  0,  0,  0,  0, 28,  0, 34,  0, 32,  0, 32,  0, 32,  0, 32,  0,252,  0, 32,  0, 32,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_117[] = {  9,  0,  0,  0,  0,  0,  0,122,  0,132,  0,132,  0,132,  0,132,  0,132,  0,132,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_119[] = {  9,  0,  0,  0,  0,  0,  0, 68,  0,170,  0,146,  0,146,  0,146,  0,130,  0,130,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_118[] = {  9,  0,  0,  0,  0,  0,  0, 16,  0, 40,  0, 40,  0, 68,  0, 68,  0,130,  0,130,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_120[] = {  9,  0,  0,  0,  0,  0,  0,130,  0, 68,  0, 40,  0, 16,  0, 40,  0, 68,  0,130,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_121[] = {  9,120,  0,132,  0,  4,  0,116,  0,140,  0,132,  0,132,  0,132,  0,132,  0,132,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_122[] = {  9,  0,  0,  0,  0,  0,  0,254,  0, 64,  0, 32,  0, 16,  0,  8,  0,  4,  0,254,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "z" */
+static const GLubyte Fixed9x15_Character_065[] = {  9,  0,  0,  0,  0,  0,  0,130,  0,130,  0,130,  0,254,  0,130,  0,130,  0,130,  0, 68,  0, 40,  0, 16,  0,  0,  0,  0,  0}; /* "A" */
+static const GLubyte Fixed9x15_Character_066[] = {  9,  0,  0,  0,  0,  0,  0,252,  0, 66,  0, 66,  0, 66,  0, 66,  0,124,  0, 66,  0, 66,  0, 66,  0,252,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_067[] = {  9,  0,  0,  0,  0,  0,  0,124,  0,130,  0,128,  0,128,  0,128,  0,128,  0,128,  0,128,  0,130,  0,124,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_068[] = {  9,  0,  0,  0,  0,  0,  0,252,  0, 66,  0, 66,  0, 66,  0, 66,  0, 66,  0, 66,  0, 66,  0, 66,  0,252,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_069[] = {  9,  0,  0,  0,  0,  0,  0,254,  0, 64,  0, 64,  0, 64,  0, 64,  0,120,  0, 64,  0, 64,  0, 64,  0,254,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_070[] = {  9,  0,  0,  0,  0,  0,  0, 64,  0, 64,  0, 64,  0, 64,  0, 64,  0,120,  0, 64,  0, 64,  0, 64,  0,254,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_071[] = {  9,  0,  0,  0,  0,  0,  0,124,  0,130,  0,130,  0,130,  0,142,  0,128,  0,128,  0,128,  0,130,  0,124,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_072[] = {  9,  0,  0,  0,  0,  0,  0,130,  0,130,  0,130,  0,130,  0,130,  0,254,  0,130,  0,130,  0,130,  0,130,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_073[] = {  9,  0,  0,  0,  0,  0,  0,248,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0,248,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_074[] = {  9,  0,  0,  0,  0,  0,  0,120,  0,132,  0,  4,  0,  4,  0,  4,  0,  4,  0,  4,  0,  4,  0,  4,  0, 30,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_075[] = {  9,  0,  0,  0,  0,  0,  0,130,  0,132,  0,136,  0,144,  0,160,  0,224,  0,144,  0,136,  0,132,  0,130,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_076[] = {  9,  0,  0,  0,  0,  0,  0,254,  0,128,  0,128,  0,128,  0,128,  0,128,  0,128,  0,128,  0,128,  0,128,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_077[] = {  9,  0,  0,  0,  0,  0,  0,130,  0,130,  0,130,  0,146,  0,146,  0,170,  0,170,  0,198,  0,130,  0,130,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_078[] = {  9,  0,  0,  0,  0,  0,  0,130,  0,130,  0,130,  0,134,  0,138,  0,146,  0,162,  0,194,  0,130,  0,130,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_079[] = {  9,  0,  0,  0,  0,  0,  0,124,  0,130,  0,130,  0,130,  0,130,  0,130,  0,130,  0,130,  0,130,  0,124,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_080[] = {  9,  0,  0,  0,  0,  0,  0,128,  0,128,  0,128,  0,128,  0,128,  0,252,  0,130,  0,130,  0,130,  0,252,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_081[] = {  9,  0,  0,  6,  0,  8,  0,124,  0,146,  0,162,  0,130,  0,130,  0,130,  0,130,  0,130,  0,130,  0,124,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_082[] = {  9,  0,  0,  0,  0,  0,  0,130,  0,130,  0,132,  0,136,  0,144,  0,252,  0,130,  0,130,  0,130,  0,252,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_083[] = {  9,  0,  0,  0,  0,  0,  0,124,  0,130,  0,130,  0,  2,  0, 12,  0,112,  0,128,  0,130,  0,130,  0,124,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_084[] = {  9,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16,  0, 16,  0, 16,  0, 16,  0, 16,  0, 16,  0,254,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_085[] = {  9,  0,  0,  0,  0,  0,  0,124,  0,130,  0,130,  0,130,  0,130,  0,130,  0,130,  0,130,  0,130,  0,130,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_087[] = {  9,  0,  0,  0,  0,  0,  0, 68,  0,170,  0,146,  0,146,  0,146,  0,146,  0,130,  0,130,  0,130,  0,130,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_086[] = {  9,  0,  0,  0,  0,  0,  0, 16,  0, 40,  0, 40,  0, 40,  0, 68,  0, 68,  0, 68,  0,130,  0,130,  0,130,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_088[] = {  9,  0,  0,  0,  0,  0,  0,130,  0,130,  0, 68,  0, 40,  0, 16,  0, 16,  0, 40,  0, 68,  0,130,  0,130,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_089[] = {  9,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16,  0, 16,  0, 16,  0, 40,  0, 68,  0,130,  0,130,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_090[] = {  9,  0,  0,  0,  0,  0,  0,254,  0,128,  0,128,  0, 64,  0, 32,  0, 16,  0,  8,  0,  4,  0,  2,  0,254,  0,  0,  0,  0,  0}; /* "Z" */
+static const GLubyte Fixed9x15_Character_048[] = {  9,  0,  0,  0,  0,  0,  0, 56,  0, 68,  0,130,  0,130,  0,130,  0,130,  0,130,  0,130,  0, 68,  0, 56,  0,  0,  0,  0,  0}; /* "0" */
+static const GLubyte Fixed9x15_Character_049[] = {  9,  0,  0,  0,  0,  0,  0,254,  0, 16,  0, 16,  0, 16,  0, 16,  0, 16,  0,144,  0, 80,  0, 48,  0, 16,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_050[] = {  9,  0,  0,  0,  0,  0,  0,254,  0,128,  0, 64,  0, 48,  0,  8,  0,  4,  0,  2,  0,130,  0,130,  0,124,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_051[] = {  9,  0,  0,  0,  0,  0,  0,124,  0,130,  0,  2,  0,  2,  0,  2,  0, 28,  0,  8,  0,  4,  0,  2,  0,254,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_052[] = {  9,  0,  0,  0,  0,  0,  0,  4,  0,  4,  0,  4,  0,254,  0,132,  0, 68,  0, 36,  0, 20,  0, 12,  0,  4,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_053[] = {  9,  0,  0,  0,  0,  0,  0,124,  0,130,  0,  2,  0,  2,  0,  2,  0,194,  0,188,  0,128,  0,128,  0,254,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_054[] = {  9,  0,  0,  0,  0,  0,  0,124,  0,130,  0,130,  0,130,  0,194,  0,188,  0,128,  0,128,  0, 64,  0, 60,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_055[] = {  9,  0,  0,  0,  0,  0,  0, 64,  0, 64,  0, 32,  0, 32,  0, 16,  0,  8,  0,  4,  0,  2,  0,  2,  0,254,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_056[] = {  9,  0,  0,  0,  0,  0,  0, 56,  0, 68,  0,130,  0,130,  0, 68,  0, 56,  0, 68,  0,130,  0, 68,  0, 56,  0,  0,  0,  0,  0};
+static const GLubyte Fixed9x15_Character_057[] = {  9,  0,  0,  0,  0,  0,  0,120,  0,  4,  0,  2,  0,  2,  0,122,  0,134,  0,130,  0,130,  0,130,  0,124,  0,  0,  0,  0,  0}; /* "9" */
+static const GLubyte Fixed9x15_Character_096[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, 32,  0, 64,  0,192,  0,  0,  0,  0,  0}; /* "`" */
+static const GLubyte Fixed9x15_Character_126[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,140,  0,146,  0, 98,  0,  0,  0,  0,  0}; /* "~" */
+static const GLubyte Fixed9x15_Character_033[] = {  9,  0,  0,  0,  0,  0,  0,128,  0,128,  0,  0,  0,  0,  0,128,  0,128,  0,128,  0,128,  0,128,  0,128,  0,128,  0,  0,  0}; /* "!" */
+static const GLubyte Fixed9x15_Character_064[] = {  9,  0,  0,  0,  0,  0,  0,124,  0,128,  0,128,  0,154,  0,166,  0,162,  0,158,  0,130,  0,130,  0,124,  0,  0,  0,  0,  0}; /* "@" */
+static const GLubyte Fixed9x15_Character_035[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0, 72,  0, 72,  0,252,  0, 72,  0, 72,  0,252,  0, 72,  0, 72,  0,  0,  0,  0,  0,  0,  0}; /* "#" */
+static const GLubyte Fixed9x15_Character_036[] = {  9,  0,  0,  0,  0, 16,  0,124,  0,146,  0, 18,  0, 18,  0, 20,  0, 56,  0, 80,  0,144,  0,146,  0,124,  0, 16,  0,  0,  0}; /* "$" */
+static const GLubyte Fixed9x15_Character_037[] = {  9,  0,  0,  0,  0,  0,  0,132,  0, 74,  0, 74,  0, 36,  0, 16,  0, 16,  0, 72,  0,164,  0,164,  0, 66,  0,  0,  0,  0,  0}; /* "%" */
+static const GLubyte Fixed9x15_Character_094[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,130,  0, 68,  0, 40,  0, 16,  0,  0,  0,  0,  0}; /* "^" */
+static const GLubyte Fixed9x15_Character_038[] = {  9,  0,  0,  0,  0,  0,  0, 98,  0,148,  0,136,  0,148,  0, 98,  0, 96,  0,144,  0,144,  0,144,  0, 96,  0,  0,  0,  0,  0}; /* "&" */
+static const GLubyte Fixed9x15_Character_042[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0,146,  0, 84,  0, 56,  0, 84,  0,146,  0, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "*" */
+static const GLubyte Fixed9x15_Character_040[] = {  9,  0,  0,  0,  0, 32,  0, 64,  0, 64,  0,128,  0,128,  0,128,  0,128,  0,128,  0,128,  0, 64,  0, 64,  0, 32,  0,  0,  0}; /* "(" */
+static const GLubyte Fixed9x15_Character_041[] = {  9,  0,  0,  0,  0,128,  0, 64,  0, 64,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 64,  0, 64,  0,128,  0,  0,  0}; /* ")" */
+static const GLubyte Fixed9x15_Character_045[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,254,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "-" */
+static const GLubyte Fixed9x15_Character_095[] = {  9,  0,  0,  0,  0,255,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "_" */
+static const GLubyte Fixed9x15_Character_061[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,254,  0,  0,  0,  0,  0,254,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "=" */
+static const GLubyte Fixed9x15_Character_043[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0,254,  0, 16,  0, 16,  0, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "+" */
+static const GLubyte Fixed9x15_Character_091[] = {  9,  0,  0,  0,  0,240,  0,128,  0,128,  0,128,  0,128,  0,128,  0,128,  0,128,  0,128,  0,128,  0,128,  0,240,  0,  0,  0}; /* "[" */
+static const GLubyte Fixed9x15_Character_123[] = {  9,  0,  0,  0,  0, 56,  0, 64,  0, 64,  0, 64,  0, 32,  0,192,  0,192,  0, 32,  0, 64,  0, 64,  0, 64,  0, 56,  0,  0,  0}; /* "{" */
+static const GLubyte Fixed9x15_Character_125[] = {  9,  0,  0,  0,  0,224,  0, 16,  0, 16,  0, 16,  0, 32,  0, 24,  0, 24,  0, 32,  0, 16,  0, 16,  0, 16,  0,224,  0,  0,  0}; /* "}" */
+static const GLubyte Fixed9x15_Character_093[] = {  9,  0,  0,  0,  0,240,  0, 16,  0, 16,  0, 16,  0, 16,  0, 16,  0, 16,  0, 16,  0, 16,  0, 16,  0, 16,  0,240,  0,  0,  0}; /* "]" */
+static const GLubyte Fixed9x15_Character_059[] = {  9,128,  0, 64,  0, 64,  0,192,  0,192,  0,  0,  0,  0,  0,  0,  0,192,  0,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* ";" */
+static const GLubyte Fixed9x15_Character_058[] = {  9,  0,  0,  0,  0,  0,  0,192,  0,192,  0,  0,  0,  0,  0,  0,  0,192,  0,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* ":" */
+static const GLubyte Fixed9x15_Character_044[] = {  9,128,  0, 64,  0, 64,  0,192,  0,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "," */
+static const GLubyte Fixed9x15_Character_046[] = {  9,  0,  0,  0,  0,  0,  0,192,  0,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "." */
+static const GLubyte Fixed9x15_Character_060[] = {  9,  0,  0,  0,  0,  0,  0,  8,  0, 16,  0, 32,  0, 64,  0,128,  0,128,  0, 64,  0, 32,  0, 16,  0,  8,  0,  0,  0,  0,  0}; /* "<" */
+static const GLubyte Fixed9x15_Character_062[] = {  9,  0,  0,  0,  0,  0,  0,128,  0, 64,  0, 32,  0, 16,  0,  8,  0,  8,  0, 16,  0, 32,  0, 64,  0,128,  0,  0,  0,  0,  0}; /* ">" */
+static const GLubyte Fixed9x15_Character_047[] = {  9,  0,  0,  0,  0,  0,  0,128,  0, 64,  0, 64,  0, 32,  0, 16,  0, 16,  0,  8,  0,  4,  0,  4,  0,  2,  0,  0,  0,  0,  0}; /* "/" */
+static const GLubyte Fixed9x15_Character_063[] = {  9,  0,  0,  0,  0,  0,  0, 16,  0,  0,  0, 16,  0, 16,  0,  8,  0,  4,  0,  2,  0,130,  0,130,  0,124,  0,  0,  0,  0,  0}; /* "?" */
+static const GLubyte Fixed9x15_Character_092[] = {  9,  0,  0,  0,  0,  0,  0,  2,  0,  4,  0,  4,  0,  8,  0, 16,  0, 16,  0, 32,  0, 64,  0, 64,  0,128,  0,  0,  0,  0,  0}; /* "\" */
+static const GLubyte Fixed9x15_Character_034[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,144,  0,144,  0,144,  0,  0,  0,  0,  0}; /* """ */
+
+/* Missing Characters filled in by John Fay by hand ... */
+static const GLubyte Fixed9x15_Character_039[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 32,  0, 32,  0, 32,  0, 32,  0,  0,  0,  0,  0}; /* "'" */
+static const GLubyte Fixed9x15_Character_124[] = {  9, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0, 32,  0,  0,  0,  0,  0}; /* "|" */
+
+
+/* The font characters mapping: */
+static const GLubyte* Fixed9x15_Character_Map[] = {Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_032,Fixed9x15_Character_033,Fixed9x15_Character_034,Fixed9x15_Character_035,Fixed9x15_Character_036,Fixed9x15_Character_037,Fixed9x15_Character_038,Fixed9x15_Character_039,Fixed9x15_Character_040,
+   Fixed9x15_Character_041,Fixed9x15_Character_042,Fixed9x15_Character_043,Fixed9x15_Character_044,Fixed9x15_Character_045,Fixed9x15_Character_046,Fixed9x15_Character_047,Fixed9x15_Character_048,Fixed9x15_Character_049,Fixed9x15_Character_050,Fixed9x15_Character_051,Fixed9x15_Character_052,Fixed9x15_Character_053,Fixed9x15_Character_054,Fixed9x15_Character_055,Fixed9x15_Character_056,Fixed9x15_Character_057,Fixed9x15_Character_058,Fixed9x15_Character_059,Fixed9x15_Character_060,Fixed9x15_Character_061,Fixed9x15_Character_062,Fixed9x15_Character_063,Fixed9x15_Character_064,Fixed9x15_Character_065,Fixed9x15_Character_066,Fixed9x15_Character_067,Fixed9x15_Character_068,Fixed9x15_Character_069,Fixed9x15_Character_070,Fixed9x15_Character_071,Fixed9x15_Character_072,Fixed9x15_Character_073,Fixed9x15_Character_074,Fixed9x15_Character_075,Fixed9x15_Character_076,Fixed9x15_Character_077,Fixed9x15_Character_078,Fixed9x15_Character_079,Fixed9x15_Character_080,Fixed9x15_Character_081,Fixed9x15_Character_082,
+   Fixed9x15_Character_083,Fixed9x15_Character_084,Fixed9x15_Character_085,Fixed9x15_Character_086,Fixed9x15_Character_087,Fixed9x15_Character_088,Fixed9x15_Character_089,Fixed9x15_Character_090,Fixed9x15_Character_091,Fixed9x15_Character_092,Fixed9x15_Character_093,Fixed9x15_Character_094,Fixed9x15_Character_095,Fixed9x15_Character_096,Fixed9x15_Character_097,Fixed9x15_Character_098,Fixed9x15_Character_099,Fixed9x15_Character_100,Fixed9x15_Character_101,Fixed9x15_Character_102,Fixed9x15_Character_103,Fixed9x15_Character_104,Fixed9x15_Character_105,Fixed9x15_Character_106,Fixed9x15_Character_107,Fixed9x15_Character_108,Fixed9x15_Character_109,Fixed9x15_Character_110,Fixed9x15_Character_111,Fixed9x15_Character_112,Fixed9x15_Character_113,Fixed9x15_Character_114,Fixed9x15_Character_115,Fixed9x15_Character_116,Fixed9x15_Character_117,Fixed9x15_Character_118,Fixed9x15_Character_119,Fixed9x15_Character_120,Fixed9x15_Character_121,Fixed9x15_Character_122,Fixed9x15_Character_123,Fixed9x15_Character_124,
+   Fixed9x15_Character_125,Fixed9x15_Character_126,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,
+   Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,
+   Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,
+   Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,Fixed9x15_Character_042,NULL};
+
+/* The font structure: */
+const SFG_Font fgFontFixed9x15 = { "-misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1", 93, 15, Fixed9x15_Character_Map, -1.0f, 3.0f };
+
+static const GLubyte Helvetica10_Character_032[] = {  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* " " */
+static const GLubyte Helvetica10_Character_097[] = {  5,  0,  0,104,144,144,112, 16,224,  0,  0,  0,  0,  0}; /* "a" */
+static const GLubyte Helvetica10_Character_098[] = {  6,  0,  0,176,200,136,136,200,176,128,128,  0,  0,  0}; /* "b" */
+static const GLubyte Helvetica10_Character_099[] = {  5,  0,  0, 96,144,128,128,144, 96,  0,  0,  0,  0,  0}; /* "c" */
+static const GLubyte Helvetica10_Character_100[] = {  6,  0,  0,104,152,136,136,152,104,  8,  8,  0,  0,  0}; /* "d" */
+static const GLubyte Helvetica10_Character_101[] = {  5,  0,  0, 96,144,128,240,144, 96,  0,  0,  0,  0,  0}; /* "e" */
+static const GLubyte Helvetica10_Character_102[] = {  4,  0,  0, 64, 64, 64, 64, 64,224, 64, 48,  0,  0,  0}; /* "f" */
+static const GLubyte Helvetica10_Character_103[] = {  6,112,  8,104,152,136,136,152,104,  0,  0,  0,  0,  0}; /* "g" */
+static const GLubyte Helvetica10_Character_104[] = {  6,  0,  0,136,136,136,136,200,176,128,128,  0,  0,  0}; /* "h" */
+static const GLubyte Helvetica10_Character_105[] = {  2,  0,  0,128,128,128,128,128,128,  0,128,  0,  0,  0}; /* "i" */
+static const GLubyte Helvetica10_Character_106[] = {  2,  0,128,128,128,128,128,128,128,  0,128,  0,  0,  0}; /* "j" */
+static const GLubyte Helvetica10_Character_107[] = {  5,  0,  0,144,144,160,192,160,144,128,128,  0,  0,  0}; /* "k" */
+static const GLubyte Helvetica10_Character_108[] = {  2,  0,  0,128,128,128,128,128,128,128,128,  0,  0,  0}; /* "l" */
+static const GLubyte Helvetica10_Character_109[] = {  8,  0,  0,146,146,146,146,146,236,  0,  0,  0,  0,  0}; /* "m" */
+static const GLubyte Helvetica10_Character_110[] = {  6,  0,  0,136,136,136,136,200,176,  0,  0,  0,  0,  0}; /* "n" */
+static const GLubyte Helvetica10_Character_111[] = {  6,  0,  0,112,136,136,136,136,112,  0,  0,  0,  0,  0}; /* "o" */
+static const GLubyte Helvetica10_Character_112[] = {  6,128,128,176,200,136,136,200,176,  0,  0,  0,  0,  0}; /* "p" */
+static const GLubyte Helvetica10_Character_113[] = {  6,  8,  8,104,152,136,136,152,104,  0,  0,  0,  0,  0}; /* "q" */
+static const GLubyte Helvetica10_Character_114[] = {  4,  0,  0,128,128,128,128,192,160,  0,  0,  0,  0,  0}; /* "r" */
+static const GLubyte Helvetica10_Character_115[] = {  5,  0,  0, 96,144, 16, 96,144, 96,  0,  0,  0,  0,  0}; /* "s" */
+static const GLubyte Helvetica10_Character_116[] = {  4,  0,  0, 96, 64, 64, 64, 64,224, 64, 64,  0,  0,  0}; /* "t" */
+static const GLubyte Helvetica10_Character_117[] = {  5,  0,  0,112,144,144,144,144,144,  0,  0,  0,  0,  0}; /* "u" */
+static const GLubyte Helvetica10_Character_118[] = {  6,  0,  0, 32, 32, 80, 80,136,136,  0,  0,  0,  0,  0}; /* "v" */
+static const GLubyte Helvetica10_Character_119[] = {  8,  0,  0, 40, 40, 84, 84,146,146,  0,  0,  0,  0,  0}; /* "w" */
+static const GLubyte Helvetica10_Character_120[] = {  6,  0,  0,136,136, 80, 32, 80,136,  0,  0,  0,  0,  0}; /* "x" */
+static const GLubyte Helvetica10_Character_121[] = {  5,128, 64, 64, 96,160,160,144,144,  0,  0,  0,  0,  0}; /* "y" */
+static const GLubyte Helvetica10_Character_122[] = {  5,  0,  0,240,128, 64, 32, 16,240,  0,  0,  0,  0,  0}; /* "z" */
+static const GLubyte Helvetica10_Character_065[] = {  7,  0,  0,130,130,124, 68, 40, 40, 16, 16,  0,  0,  0}; /* "A" */
+static const GLubyte Helvetica10_Character_066[] = {  7,  0,  0,240,136,136,136,240,136,136,240,  0,  0,  0}; /* "B" */
+static const GLubyte Helvetica10_Character_067[] = {  8,  0,  0,120,132,128,128,128,128,132,120,  0,  0,  0}; /* "C" */
+static const GLubyte Helvetica10_Character_068[] = {  8,  0,  0,240,136,132,132,132,132,136,240,  0,  0,  0}; /* "D" */
+static const GLubyte Helvetica10_Character_069[] = {  7,  0,  0,248,128,128,128,248,128,128,248,  0,  0,  0}; /* "E" */
+static const GLubyte Helvetica10_Character_070[] = {  6,  0,  0,128,128,128,128,240,128,128,248,  0,  0,  0}; /* "F" */
+static const GLubyte Helvetica10_Character_071[] = {  8,  0,  0,116,140,132,140,128,128,132,120,  0,  0,  0}; /* "G" */
+static const GLubyte Helvetica10_Character_072[] = {  8,  0,  0,132,132,132,132,252,132,132,132,  0,  0,  0}; /* "H" */
+static const GLubyte Helvetica10_Character_073[] = {  3,  0,  0,128,128,128,128,128,128,128,128,  0,  0,  0}; /* "I" */
+static const GLubyte Helvetica10_Character_074[] = {  5,  0,  0, 96,144, 16, 16, 16, 16, 16, 16,  0,  0,  0}; /* "J" */
+static const GLubyte Helvetica10_Character_075[] = {  7,  0,  0,136,136,144,144,224,160,144,136,  0,  0,  0}; /* "K" */
+static const GLubyte Helvetica10_Character_076[] = {  6,  0,  0,240,128,128,128,128,128,128,128,  0,  0,  0}; /* "L" */
+static const GLubyte Helvetica10_Character_077[] = {  9,  0,  0,  0,  0,146,  0,146,  0,146,  0,170,  0,170,  0,198,  0,198,  0,130,  0,  0,  0,  0,  0,  0,  0}; /* "M" */
+static const GLubyte Helvetica10_Character_078[] = {  8,  0,  0,140,140,148,148,164,164,196,196,  0,  0,  0}; /* "N" */
+static const GLubyte Helvetica10_Character_079[] = {  8,  0,  0,120,132,132,132,132,132,132,120,  0,  0,  0}; /* "O" */
+static const GLubyte Helvetica10_Character_080[] = {  7,  0,  0,128,128,128,128,240,136,136,240,  0,  0,  0}; /* "P" */
+static const GLubyte Helvetica10_Character_081[] = {  8,  0,  2,124,140,148,132,132,132,132,120,  0,  0,  0}; /* "Q" */
+static const GLubyte Helvetica10_Character_082[] = {  7,  0,  0,136,136,136,136,240,136,136,240,  0,  0,  0}; /* "R" */
+static const GLubyte Helvetica10_Character_083[] = {  7,  0,  0,112,136,136,  8,112,128,136,112,  0,  0,  0}; /* "S" */
+static const GLubyte Helvetica10_Character_084[] = {  5,  0,  0, 32, 32, 32, 32, 32, 32, 32,248,  0,  0,  0}; /* "T" */
+static const GLubyte Helvetica10_Character_085[] = {  8,  0,  0,120,132,132,132,132,132,132,132,  0,  0,  0}; /* "U" */
+static const GLubyte Helvetica10_Character_086[] = {  7,  0,  0, 16, 40, 40, 68, 68, 68,130,130,  0,  0,  0}; /* "V" */
+static const GLubyte Helvetica10_Character_087[] = {  9,  0,  0,  0,  0, 34,  0, 34,  0, 34,  0, 85,  0, 73,  0, 73,  0,136,128,136,128,  0,  0,  0,  0,  0,  0}; /* "W" */
+static const GLubyte Helvetica10_Character_088[] = {  7,  0,  0,136,136, 80, 80, 32, 80,136,136,  0,  0,  0}; /* "X" */
+static const GLubyte Helvetica10_Character_089[] = {  7,  0,  0, 16, 16, 16, 40, 40, 68, 68,130,  0,  0,  0}; /* "Y" */
+static const GLubyte Helvetica10_Character_090[] = {  7,  0,  0,248,128, 64, 32, 32, 16,  8,248,  0,  0,  0}; /* "Z" */
+static const GLubyte Helvetica10_Character_048[] = {  6,  0,  0,112,136,136,136,136,136,136,112,  0,  0,  0}; /* "0" */
+static const GLubyte Helvetica10_Character_049[] = {  6,  0,  0, 64, 64, 64, 64, 64, 64,192, 64,  0,  0,  0}; /* "1" */
+static const GLubyte Helvetica10_Character_050[] = {  6,  0,  0,248,128, 64, 48,  8,  8,136,112,  0,  0,  0}; /* "2" */
+static const GLubyte Helvetica10_Character_051[] = {  6,  0,  0,112,136,  8,  8, 48,  8,136,112,  0,  0,  0}; /* "3" */
+static const GLubyte Helvetica10_Character_052[] = {  6,  0,  0, 16, 16,248,144, 80, 80, 48, 16,  0,  0,  0}; /* "4" */
+static const GLubyte Helvetica10_Character_053[] = {  6,  0,  0,112,136,  8,  8,240,128,128,248,  0,  0,  0}; /* "5" */
+static const GLubyte Helvetica10_Character_054[] = {  6,  0,  0,112,136,136,200,176,128,136,112,  0,  0,  0}; /* "6" */
+static const GLubyte Helvetica10_Character_055[] = {  6,  0,  0, 64, 64, 32, 32, 16, 16,  8,248,  0,  0,  0}; /* "7" */
+static const GLubyte Helvetica10_Character_056[] = {  6,  0,  0,112,136,136,136,112,136,136,112,  0,  0,  0}; /* "8" */
+static const GLubyte Helvetica10_Character_057[] = {  6,  0,  0,112,136,  8,104,152,136,136,112,  0,  0,  0}; /* "9" */
+static const GLubyte Helvetica10_Character_096[] = {  3,  0,  0,  0,  0,  0,  0,  0,128,128, 64,  0,  0,  0}; /* "`" */
+static const GLubyte Helvetica10_Character_126[] = {  7,  0,  0,  0,  0,  0,152,100,  0,  0,  0,  0,  0,  0}; /* "~" */
+static const GLubyte Helvetica10_Character_033[] = {  3,  0,  0,128,  0,128,128,128,128,128,128,  0,  0,  0}; /* "!" */
+static const GLubyte Helvetica10_Character_064[] = { 11, 62,  0, 64,  0,155,  0,164,128,164,128,162, 64,146, 64, 77, 64, 32,128, 31,  0,  0,  0,  0,  0,  0,  0}; /* "@" */
+static const GLubyte Helvetica10_Character_035[] = {  6,  0,  0, 80, 80,248, 40,124, 40, 40,  0,  0,  0,  0}; /* "#" */
+static const GLubyte Helvetica10_Character_036[] = {  6,  0, 32,112,168, 40,112,160,168,112, 32,  0,  0,  0}; /* "$" */
+static const GLubyte Helvetica10_Character_037[] = {  9,  0,  0,  0,  0, 38,  0, 41,  0, 22,  0, 16,  0,  8,  0,104,  0,148,  0,100,  0,  0,  0,  0,  0,  0,  0}; /* "%" */
+static const GLubyte Helvetica10_Character_094[] = {  6,  0,  0,  0,  0,  0,136, 80, 80, 32, 32,  0,  0,  0}; /* "^" */
+static const GLubyte Helvetica10_Character_038[] = {  8,  0,  0,100,152,152,164, 96, 80, 80, 32,  0,  0,  0}; /* "&" */
+static const GLubyte Helvetica10_Character_042[] = {  4,  0,  0,  0,  0,  0,  0,  0,160, 64,160,  0,  0,  0}; /* "*" */
+static const GLubyte Helvetica10_Character_040[] = {  4, 32, 64, 64,128,128,128,128, 64, 64, 32,  0,  0,  0}; /* "(" */
+static const GLubyte Helvetica10_Character_041[] = {  4,128, 64, 64, 32, 32, 32, 32, 64, 64,128,  0,  0,  0}; /* ")" */
+static const GLubyte Helvetica10_Character_045[] = {  7,  0,  0,  0,  0,  0,248,  0,  0,  0,  0,  0,  0,  0}; /* "-" */
+static const GLubyte Helvetica10_Character_095[] = {  6,252,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "_" */
+static const GLubyte Helvetica10_Character_061[] = {  5,  0,  0,  0,  0,240,  0,240,  0,  0,  0,  0,  0,  0}; /* "=" */
+static const GLubyte Helvetica10_Character_043[] = {  6,  0,  0,  0, 32, 32,248, 32, 32,  0,  0,  0,  0,  0}; /* "+" */
+static const GLubyte Helvetica10_Character_091[] = {  3,192,128,128,128,128,128,128,128,128,192,  0,  0,  0}; /* "[" */
+static const GLubyte Helvetica10_Character_123[] = {  3, 32, 64, 64, 64, 64,128, 64, 64, 64, 32,  0,  0,  0}; /* "{" */
+static const GLubyte Helvetica10_Character_125[] = {  3,128, 64, 64, 64, 64, 32, 64, 64, 64,128,  0,  0,  0}; /* "}" */
+static const GLubyte Helvetica10_Character_093[] = {  3,192, 64, 64, 64, 64, 64, 64, 64, 64,192,  0,  0,  0}; /* "]" */
+static const GLubyte Helvetica10_Character_059[] = {  3,128, 64, 64,  0,  0,  0,  0, 64,  0,  0,  0,  0,  0}; /* ";" */
+static const GLubyte Helvetica10_Character_058[] = {  3,  0,  0,128,  0,  0,  0,  0,128,  0,  0,  0,  0,  0}; /* ":" */
+static const GLubyte Helvetica10_Character_044[] = {  3,128, 64, 64,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "," */
+static const GLubyte Helvetica10_Character_046[] = {  3,  0,  0,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "." */
+static const GLubyte Helvetica10_Character_060[] = {  6,  0,  0,  0, 32, 64,128, 64, 32,  0,  0,  0,  0,  0}; /* "<" */
+static const GLubyte Helvetica10_Character_062[] = {  6,  0,  0,  0,128, 64, 32, 64,128,  0,  0,  0,  0,  0}; /* ">" */
+static const GLubyte Helvetica10_Character_047[] = {  3,  0,  0,128,128, 64, 64, 64, 64, 32, 32,  0,  0,  0}; /* "/" */
+static const GLubyte Helvetica10_Character_063[] = {  6,  0,  0, 64,  0, 64, 64, 32, 16,144, 96,  0,  0,  0}; /* "?" */
+static const GLubyte Helvetica10_Character_092[] = {  3,  0,  0, 32, 32, 64, 64, 64, 64,128,128,  0,  0,  0}; /* "\" */
+static const GLubyte Helvetica10_Character_034[] = {  4,  0,  0,  0,  0,  0,  0,  0,  0,160,160,  0,  0,  0}; /* """ */
+
+/* Missing Characters filled in by John Fay by hand ... */
+static const GLubyte Helvetica10_Character_039[] = {  3,  0,  0,  0,  0,  0,  0,  0,128, 64, 64,  0,  0,  0}; /* "'" */
+static const GLubyte Helvetica10_Character_124[] = {  3, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,  0,  0}; /* "|" */
+
+
+/* The font characters mapping: */
+static const GLubyte* Helvetica10_Character_Map[] = {Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_032,Helvetica10_Character_033,Helvetica10_Character_034,Helvetica10_Character_035,Helvetica10_Character_036,Helvetica10_Character_037,
+ Helvetica10_Character_038,Helvetica10_Character_039,Helvetica10_Character_040,Helvetica10_Character_041,Helvetica10_Character_042,Helvetica10_Character_043,Helvetica10_Character_044,Helvetica10_Character_045,Helvetica10_Character_046,Helvetica10_Character_047,Helvetica10_Character_048,Helvetica10_Character_049,Helvetica10_Character_050,Helvetica10_Character_051,Helvetica10_Character_052,Helvetica10_Character_053,Helvetica10_Character_054,Helvetica10_Character_055,Helvetica10_Character_056,Helvetica10_Character_057,Helvetica10_Character_058,Helvetica10_Character_059,Helvetica10_Character_060,Helvetica10_Character_061,Helvetica10_Character_062,Helvetica10_Character_063,Helvetica10_Character_064,Helvetica10_Character_065,Helvetica10_Character_066,Helvetica10_Character_067,Helvetica10_Character_068,Helvetica10_Character_069,Helvetica10_Character_070,Helvetica10_Character_071,Helvetica10_Character_072,Helvetica10_Character_073,Helvetica10_Character_074,Helvetica10_Character_075,Helvetica10_Character_076,
+ Helvetica10_Character_077,Helvetica10_Character_078,Helvetica10_Character_079,Helvetica10_Character_080,Helvetica10_Character_081,Helvetica10_Character_082,Helvetica10_Character_083,Helvetica10_Character_084,Helvetica10_Character_085,Helvetica10_Character_086,Helvetica10_Character_087,Helvetica10_Character_088,Helvetica10_Character_089,Helvetica10_Character_090,Helvetica10_Character_091,Helvetica10_Character_092,Helvetica10_Character_093,Helvetica10_Character_094,Helvetica10_Character_095,Helvetica10_Character_096,Helvetica10_Character_097,Helvetica10_Character_098,Helvetica10_Character_099,Helvetica10_Character_100,Helvetica10_Character_101,Helvetica10_Character_102,Helvetica10_Character_103,Helvetica10_Character_104,Helvetica10_Character_105,Helvetica10_Character_106,Helvetica10_Character_107,Helvetica10_Character_108,Helvetica10_Character_109,Helvetica10_Character_110,Helvetica10_Character_111,Helvetica10_Character_112,Helvetica10_Character_113,Helvetica10_Character_114,Helvetica10_Character_115,
+ Helvetica10_Character_116,Helvetica10_Character_117,Helvetica10_Character_118,Helvetica10_Character_119,Helvetica10_Character_120,Helvetica10_Character_121,Helvetica10_Character_122,Helvetica10_Character_123,Helvetica10_Character_124,Helvetica10_Character_125,Helvetica10_Character_126,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,
+ Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,
+ Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,
+ Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,Helvetica10_Character_042,NULL};
+
+/* The font structure: */
+const SFG_Font fgFontHelvetica10 = { "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1", 93, 13, Helvetica10_Character_Map, -1.0f, 2.0f };
+
+static const GLubyte Helvetica12_Character_032[] = {  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* " " */
+static const GLubyte Helvetica12_Character_097[] = {  7,  0,  0,  0,116,136,136,120,  8,136,112,  0,  0,  0,  0,  0}; /* "a" */
+static const GLubyte Helvetica12_Character_098[] = {  7,  0,  0,  0,176,200,136,136,136,200,176,128,128,  0,  0,  0}; /* "b" */
+static const GLubyte Helvetica12_Character_099[] = {  7,  0,  0,  0,112,136,128,128,128,136,112,  0,  0,  0,  0,  0}; /* "c" */
+static const GLubyte Helvetica12_Character_100[] = {  7,  0,  0,  0,104,152,136,136,136,152,104,  8,  8,  0,  0,  0}; /* "d" */
+static const GLubyte Helvetica12_Character_101[] = {  7,  0,  0,  0,112,136,128,248,136,136,112,  0,  0,  0,  0,  0}; /* "e" */
+static const GLubyte Helvetica12_Character_102[] = {  3,  0,  0,  0, 64, 64, 64, 64, 64, 64,224, 64, 48,  0,  0,  0}; /* "f" */
+static const GLubyte Helvetica12_Character_103[] = {  7,112,136,  8,104,152,136,136,136,152,104,  0,  0,  0,  0,  0}; /* "g" */
+static const GLubyte Helvetica12_Character_104[] = {  7,  0,  0,  0,136,136,136,136,136,200,176,128,128,  0,  0,  0}; /* "h" */
+static const GLubyte Helvetica12_Character_105[] = {  3,  0,  0,  0,128,128,128,128,128,128,128,  0,128,  0,  0,  0}; /* "i" */
+static const GLubyte Helvetica12_Character_106[] = {  3,128, 64, 64, 64, 64, 64, 64, 64, 64, 64,  0, 64,  0,  0,  0}; /* "j" */
+static const GLubyte Helvetica12_Character_107[] = {  6,  0,  0,  0,136,144,160,192,192,160,144,128,128,  0,  0,  0}; /* "k" */
+static const GLubyte Helvetica12_Character_108[] = {  3,  0,  0,  0,128,128,128,128,128,128,128,128,128,  0,  0,  0}; /* "l" */
+static const GLubyte Helvetica12_Character_109[] = {  9,  0,  0,  0,  0,  0,  0,146,  0,146,  0,146,  0,146,  0,146,  0,218,  0,164,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "m" */
+static const GLubyte Helvetica12_Character_110[] = {  7,  0,  0,  0,136,136,136,136,136,200,176,  0,  0,  0,  0,  0}; /* "n" */
+static const GLubyte Helvetica12_Character_111[] = {  7,  0,  0,  0,112,136,136,136,136,136,112,  0,  0,  0,  0,  0}; /* "o" */
+static const GLubyte Helvetica12_Character_112[] = {  7,128,128,128,176,200,136,136,136,200,176,  0,  0,  0,  0,  0}; /* "p" */
+static const GLubyte Helvetica12_Character_113[] = {  7,  8,  8,  8,104,152,136,136,136,152,104,  0,  0,  0,  0,  0}; /* "q" */
+static const GLubyte Helvetica12_Character_114[] = {  4,  0,  0,  0,128,128,128,128,128,192,160,  0,  0,  0,  0,  0}; /* "r" */
+static const GLubyte Helvetica12_Character_115[] = {  6,  0,  0,  0, 96,144, 16, 96,128,144, 96,  0,  0,  0,  0,  0}; /* "s" */
+static const GLubyte Helvetica12_Character_116[] = {  4,  0,  0,  0, 96, 64, 64, 64, 64, 64,224, 64, 64,  0,  0,  0}; /* "t" */
+static const GLubyte Helvetica12_Character_117[] = {  7,  0,  0,  0,104,152,136,136,136,136,136,  0,  0,  0,  0,  0}; /* "u" */
+static const GLubyte Helvetica12_Character_118[] = {  7,  0,  0,  0, 32, 32, 80, 80,136,136,136,  0,  0,  0,  0,  0}; /* "v" */
+static const GLubyte Helvetica12_Character_119[] = { 10,  0,  0,  0,  0,  0,  0, 34,  0, 34,  0, 85,  0, 73,  0, 73,  0,136,128,136,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "w" */
+static const GLubyte Helvetica12_Character_120[] = {  6,  0,  0,  0,132,132, 72, 48, 48, 72,132,  0,  0,  0,  0,  0}; /* "x" */
+static const GLubyte Helvetica12_Character_121[] = {  7,128, 64, 32, 32, 80, 80,144,136,136,136,  0,  0,  0,  0,  0}; /* "y" */
+static const GLubyte Helvetica12_Character_122[] = {  6,  0,  0,  0,240,128, 64, 64, 32, 16,240,  0,  0,  0,  0,  0}; /* "z" */
+static const GLubyte Helvetica12_Character_065[] = {  9,  0,  0,  0,  0,  0,  0,130,  0,130,  0,130,  0,124,  0, 68,  0, 68,  0, 40,  0, 40,  0, 16,  0,  0,  0,  0,  0,  0,  0}; /* "A" */
+static const GLubyte Helvetica12_Character_066[] = {  8,  0,  0,  0,248,132,132,132,248,132,132,132,248,  0,  0,  0}; /* "B" */
+static const GLubyte Helvetica12_Character_067[] = {  9,  0,  0,  0,  0,  0,  0, 60,  0, 66,  0,128,  0,128,  0,128,  0,128,  0,128,  0, 66,  0, 60,  0,  0,  0,  0,  0,  0,  0}; /* "C" */
+static const GLubyte Helvetica12_Character_068[] = {  9,  0,  0,  0,  0,  0,  0,248,  0,132,  0,130,  0,130,  0,130,  0,130,  0,130,  0,132,  0,248,  0,  0,  0,  0,  0,  0,  0}; /* "D" */
+static const GLubyte Helvetica12_Character_069[] = {  8,  0,  0,  0,252,128,128,128,252,128,128,128,252,  0,  0,  0}; /* "E" */
+static const GLubyte Helvetica12_Character_070[] = {  8,  0,  0,  0,128,128,128,128,248,128,128,128,252,  0,  0,  0}; /* "F" */
+static const GLubyte Helvetica12_Character_071[] = {  9,  0,  0,  0,  0,  0,  0, 58,  0, 70,  0,130,  0,130,  0,142,  0,128,  0,128,  0, 66,  0, 60,  0,  0,  0,  0,  0,  0,  0}; /* "G" */
+static const GLubyte Helvetica12_Character_072[] = {  9,  0,  0,  0,  0,  0,  0,130,  0,130,  0,130,  0,130,  0,254,  0,130,  0,130,  0,130,  0,130,  0,  0,  0,  0,  0,  0,  0}; /* "H" */
+static const GLubyte Helvetica12_Character_073[] = {  3,  0,  0,  0,128,128,128,128,128,128,128,128,128,  0,  0,  0}; /* "I" */
+static const GLubyte Helvetica12_Character_074[] = {  7,  0,  0,  0,112,136,136,  8,  8,  8,  8,  8,  8,  0,  0,  0}; /* "J" */
+static const GLubyte Helvetica12_Character_075[] = {  8,  0,  0,  0,130,132,136,144,224,160,144,136,132,  0,  0,  0}; /* "K" */
+static const GLubyte Helvetica12_Character_076[] = {  7,  0,  0,  0,248,128,128,128,128,128,128,128,128,  0,  0,  0}; /* "L" */
+static const GLubyte Helvetica12_Character_077[] = { 11,  0,  0,  0,  0,  0,  0,136,128,136,128,148,128,148,128,162,128,162,128,193,128,193,128,128,128,  0,  0,  0,  0,  0,  0}; /* "M" */
+static const GLubyte Helvetica12_Character_078[] = {  9,  0,  0,  0,  0,  0,  0,130,  0,134,  0,138,  0,138,  0,146,  0,162,  0,162,  0,194,  0,130,  0,  0,  0,  0,  0,  0,  0}; /* "N" */
+static const GLubyte Helvetica12_Character_079[] = { 10,  0,  0,  0,  0,  0,  0, 60,  0, 66,  0,129,  0,129,  0,129,  0,129,  0,129,  0, 66,  0, 60,  0,  0,  0,  0,  0,  0,  0}; /* "O" */
+static const GLubyte Helvetica12_Character_080[] = {  8,  0,  0,  0,128,128,128,128,248,132,132,132,248,  0,  0,  0}; /* "P" */
+static const GLubyte Helvetica12_Character_081[] = { 10,  0,  0,  0,  0,  0,  0, 61,  0, 66,  0,133,  0,137,  0,129,  0,129,  0,129,  0, 66,  0, 60,  0,  0,  0,  0,  0,  0,  0}; /* "Q" */
+static const GLubyte Helvetica12_Character_082[] = {  8,  0,  0,  0,132,132,132,136,248,132,132,132,248,  0,  0,  0}; /* "R" */
+static const GLubyte Helvetica12_Character_083[] = {  8,  0,  0,  0,120,132,132,  4, 24, 96,128,132,120,  0,  0,  0}; /* "S" */
+static const GLubyte Helvetica12_Character_084[] = {  7,  0,  0,  0, 16, 16, 16, 16, 16, 16, 16, 16,254,  0,  0,  0}; /* "T" */
+static const GLubyte Helvetica12_Character_085[] = {  8,  0,  0,  0,120,132,132,132,132,132,132,132,132,  0,  0,  0}; /* "U" */
+static const GLubyte Helvetica12_Character_086[] = {  9,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 40,  0, 40,  0, 68,  0, 68,  0, 68,  0,130,  0,130,  0,  0,  0,  0,  0,  0,  0}; /* "V" */
+static const GLubyte Helvetica12_Character_087[] = { 11,  0,  0,  0,  0,  0,  0, 34,  0, 34,  0, 34,  0, 85,  0, 85,  0, 73,  0,136,128,136,128,136,128,  0,  0,  0,  0,  0,  0}; /* "W" */
+static const GLubyte Helvetica12_Character_088[] = {  9,  0,  0,  0,  0,  0,  0,130,  0, 68,  0, 68,  0, 40,  0, 16,  0, 40,  0, 68,  0, 68,  0,130,  0,  0,  0,  0,  0,  0,  0}; /* "X" */
+static const GLubyte Helvetica12_Character_089[] = {  9,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16,  0, 40,  0, 68,  0, 68,  0,130,  0,130,  0,  0,  0,  0,  0,  0,  0}; /* "Y" */
+static const GLubyte Helvetica12_Character_090[] = {  9,  0,  0,  0,  0,  0,  0,254,  0,128,  0, 64,  0, 32,  0, 16,  0,  8,  0,  4,  0,  2,  0,254,  0,  0,  0,  0,  0,  0,  0}; /* "Z" */
+static const GLubyte Helvetica12_Character_048[] = {  7,  0,  0,  0,112,136,136,136,136,136,136,136,112,  0,  0,  0}; /* "0" */
+static const GLubyte Helvetica12_Character_049[] = {  7,  0,  0,  0, 32, 32, 32, 32, 32, 32, 32,224, 32,  0,  0,  0}; /* "1" */
+static const GLubyte Helvetica12_Character_050[] = {  7,  0,  0,  0,248,128,128, 64, 32, 16,  8,136,112,  0,  0,  0}; /* "2" */
+static const GLubyte Helvetica12_Character_051[] = {  7,  0,  0,  0,112,136,136,  8,  8, 48,  8,136,112,  0,  0,  0}; /* "3" */
+static const GLubyte Helvetica12_Character_052[] = {  7,  0,  0,  0,  8,  8,252,136, 72, 40, 40, 24,  8,  0,  0,  0}; /* "4" */
+static const GLubyte Helvetica12_Character_053[] = {  7,  0,  0,  0,112,136,136,  8,  8,240,128,128,248,  0,  0,  0}; /* "5" */
+static const GLubyte Helvetica12_Character_054[] = {  7,  0,  0,  0,112,136,136,136,200,176,128,136,112,  0,  0,  0}; /* "6" */
+static const GLubyte Helvetica12_Character_055[] = {  7,  0,  0,  0, 64, 64, 32, 32, 32, 16, 16,  8,248,  0,  0,  0}; /* "7" */
+static const GLubyte Helvetica12_Character_056[] = {  7,  0,  0,  0,112,136,136,136,136,112,136,136,112,  0,  0,  0}; /* "8" */
+static const GLubyte Helvetica12_Character_057[] = {  7,  0,  0,  0,112,136,  8,  8,120,136,136,136,112,  0,  0,  0}; /* "9" */
+static const GLubyte Helvetica12_Character_096[] = {  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,192,128, 64,  0,  0,  0}; /* "`" */
+static const GLubyte Helvetica12_Character_126[] = {  8,  0,  0,  0,  0,  0,  0,152,100,  0,  0,  0,  0,  0,  0,  0}; /* "~" */
+static const GLubyte Helvetica12_Character_033[] = {  3,  0,  0,  0,128,  0,128,128,128,128,128,128,128,  0,  0,  0}; /* "!" */
+static const GLubyte Helvetica12_Character_064[] = { 12,  0,  0,  0,  0, 62,  0, 64,  0,155,  0,166,128,162, 64,162, 64,146, 64, 77, 64, 96,128, 31,  0,  0,  0,  0,  0,  0,  0}; /* "@" */
+static const GLubyte Helvetica12_Character_035[] = {  7,  0,  0,  0, 80, 80, 80,252, 40,252, 40, 40,  0,  0,  0,  0}; /* "#" */
+static const GLubyte Helvetica12_Character_036[] = {  7,  0,  0, 32,112,168,168, 40,112,160,168,112, 32,  0,  0,  0}; /* "$" */
+static const GLubyte Helvetica12_Character_037[] = { 11,  0,  0,  0,  0,  0,  0, 35,  0, 20,128, 20,128, 19,  0,  8,  0,104,  0,148,  0,148,  0, 98,  0,  0,  0,  0,  0,  0,  0}; /* "%" */
+static const GLubyte Helvetica12_Character_094[] = {  6,  0,  0,  0,  0,  0,  0,  0,  0,136, 80, 32,  0,  0,  0,  0}; /* "^" */
+static const GLubyte Helvetica12_Character_038[] = {  9,  0,  0,  0,  0,  0,  0,114,  0,140,  0,132,  0,138,  0, 80,  0, 48,  0, 72,  0, 72,  0, 48,  0,  0,  0,  0,  0,  0,  0}; /* "&" */
+static const GLubyte Helvetica12_Character_042[] = {  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,160, 64,160,  0,  0,  0}; /* "*" */
+static const GLubyte Helvetica12_Character_040[] = {  4, 32, 64, 64,128,128,128,128,128,128, 64, 64, 32,  0,  0,  0}; /* "(" */
+static const GLubyte Helvetica12_Character_041[] = {  4,128, 64, 64, 32, 32, 32, 32, 32, 32, 64, 64,128,  0,  0,  0}; /* ")" */
+static const GLubyte Helvetica12_Character_045[] = {  8,  0,  0,  0,  0,  0,  0,248,  0,  0,  0,  0,  0,  0,  0,  0}; /* "-" */
+static const GLubyte Helvetica12_Character_095[] = {  7,  0,255,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "_" */
+static const GLubyte Helvetica12_Character_061[] = {  7,  0,  0,  0,  0,  0,248,  0,248,  0,  0,  0,  0,  0,  0,  0}; /* "=" */
+static const GLubyte Helvetica12_Character_043[] = {  7,  0,  0,  0,  0, 32, 32,248, 32, 32,  0,  0,  0,  0,  0,  0}; /* "+" */
+static const GLubyte Helvetica12_Character_091[] = {  3,192,128,128,128,128,128,128,128,128,128,128,192,  0,  0,  0}; /* "[" */
+static const GLubyte Helvetica12_Character_123[] = {  4, 48, 64, 64, 64, 64, 64,128, 64, 64, 64, 64, 48,  0,  0,  0}; /* "{" */
+static const GLubyte Helvetica12_Character_125[] = {  4,192, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32,192,  0,  0,  0}; /* "}" */
+static const GLubyte Helvetica12_Character_093[] = {  3,192, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,192,  0,  0,  0}; /* "]" */
+static const GLubyte Helvetica12_Character_059[] = {  3,  0,128, 64, 64,  0,  0,  0,  0, 64,  0,  0,  0,  0,  0,  0}; /* ";" */
+static const GLubyte Helvetica12_Character_058[] = {  3,  0,  0,  0,128,  0,  0,  0,  0,128,  0,  0,  0,  0,  0,  0}; /* ":" */
+static const GLubyte Helvetica12_Character_044[] = {  4,  0,128, 64, 64,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "," */
+static const GLubyte Helvetica12_Character_046[] = {  3,  0,  0,  0,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "." */
+static const GLubyte Helvetica12_Character_060[] = {  7,  0,  0,  0,  0, 12, 48,192, 48, 12,  0,  0,  0,  0,  0,  0}; /* "<" */
+static const GLubyte Helvetica12_Character_062[] = {  7,  0,  0,  0,  0,192, 48, 12, 48,192,  0,  0,  0,  0,  0,  0}; /* ">" */
+static const GLubyte Helvetica12_Character_047[] = {  4,  0,  0,  0,128,128,128, 64, 64, 64, 32, 32, 32,  0,  0,  0}; /* "/" */
+static const GLubyte Helvetica12_Character_063[] = {  7,  0,  0,  0, 32,  0, 32, 32, 16, 16,136,136,112,  0,  0,  0}; /* "?" */
+static const GLubyte Helvetica12_Character_092[] = {  4,  0,  0,  0, 32, 32, 32, 64, 64, 64,128,128,128,  0,  0,  0}; /* "\" */
+static const GLubyte Helvetica12_Character_034[] = {  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,160,160,160,  0,  0,  0}; /* """ */
+
+/* Missing Characters filled in by John Fay by hand ... */
+static const GLubyte Helvetica12_Character_039[] = {  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,128, 64, 64,  0,  0}; /* "'" */
+static const GLubyte Helvetica12_Character_124[] = {  3, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  0,  0}; /* "|" */
+
+
+/* The font characters mapping: */
+static const GLubyte* Helvetica12_Character_Map[] = {Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_032,Helvetica12_Character_033,Helvetica12_Character_034,Helvetica12_Character_035,Helvetica12_Character_036,Helvetica12_Character_037,
+ Helvetica12_Character_038,Helvetica12_Character_039,Helvetica12_Character_040,Helvetica12_Character_041,Helvetica12_Character_042,Helvetica12_Character_043,Helvetica12_Character_044,Helvetica12_Character_045,Helvetica12_Character_046,Helvetica12_Character_047,Helvetica12_Character_048,Helvetica12_Character_049,Helvetica12_Character_050,Helvetica12_Character_051,Helvetica12_Character_052,Helvetica12_Character_053,Helvetica12_Character_054,Helvetica12_Character_055,Helvetica12_Character_056,Helvetica12_Character_057,Helvetica12_Character_058,Helvetica12_Character_059,Helvetica12_Character_060,Helvetica12_Character_061,Helvetica12_Character_062,Helvetica12_Character_063,Helvetica12_Character_064,Helvetica12_Character_065,Helvetica12_Character_066,Helvetica12_Character_067,Helvetica12_Character_068,Helvetica12_Character_069,Helvetica12_Character_070,Helvetica12_Character_071,Helvetica12_Character_072,Helvetica12_Character_073,Helvetica12_Character_074,Helvetica12_Character_075,Helvetica12_Character_076,
+ Helvetica12_Character_077,Helvetica12_Character_078,Helvetica12_Character_079,Helvetica12_Character_080,Helvetica12_Character_081,Helvetica12_Character_082,Helvetica12_Character_083,Helvetica12_Character_084,Helvetica12_Character_085,Helvetica12_Character_086,Helvetica12_Character_087,Helvetica12_Character_088,Helvetica12_Character_089,Helvetica12_Character_090,Helvetica12_Character_091,Helvetica12_Character_092,Helvetica12_Character_093,Helvetica12_Character_094,Helvetica12_Character_095,Helvetica12_Character_096,Helvetica12_Character_097,Helvetica12_Character_098,Helvetica12_Character_099,Helvetica12_Character_100,Helvetica12_Character_101,Helvetica12_Character_102,Helvetica12_Character_103,Helvetica12_Character_104,Helvetica12_Character_105,Helvetica12_Character_106,Helvetica12_Character_107,Helvetica12_Character_108,Helvetica12_Character_109,Helvetica12_Character_110,Helvetica12_Character_111,Helvetica12_Character_112,Helvetica12_Character_113,Helvetica12_Character_114,Helvetica12_Character_115,
+ Helvetica12_Character_116,Helvetica12_Character_117,Helvetica12_Character_118,Helvetica12_Character_119,Helvetica12_Character_120,Helvetica12_Character_121,Helvetica12_Character_122,Helvetica12_Character_123,Helvetica12_Character_124,Helvetica12_Character_125,Helvetica12_Character_126,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,
+ Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,
+ Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,
+ Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,Helvetica12_Character_042,NULL};
+
+/* The font structure: */
+const SFG_Font fgFontHelvetica12 = { "-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1", 93, 15, Helvetica12_Character_Map, -1.0f, 3.0f };
+
+static const GLubyte Helvetica18_Character_032[] = {  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* " " */
+static const GLubyte Helvetica18_Character_097[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0,118,  0,238,  0,198,  0,198,  0,230,  0,126,  0, 14,  0,198,  0,238,  0,124,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "a" */
+static const GLubyte Helvetica18_Character_098[] = { 11,  0,  0,  0,  0,  0,  0,  0,  0,222,  0,255,  0,227,  0,193,128,193,128,193,128,193,128,227,  0,255,  0,222,  0,192,  0,192,  0,192,  0,192,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "b" */
+static const GLubyte Helvetica18_Character_099[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,127,  0, 99,  0,192,  0,192,  0,192,  0,192,  0, 99,  0,127,  0, 62,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "c" */
+static const GLubyte Helvetica18_Character_100[] = { 11,  0,  0,  0,  0,  0,  0,  0,  0, 61,128,127,128, 99,128,193,128,193,128,193,128,193,128, 99,128,127,128, 61,128,  1,128,  1,128,  1,128,  1,128,  0,  0,  0,  0,  0,  0,  0,  0}; /* "d" */
+static const GLubyte Helvetica18_Character_101[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0, 60,  0,127,  0,227,  0,192,  0,192,  0,255,  0,195,  0,195,  0,126,  0, 60,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "e" */
+static const GLubyte Helvetica18_Character_102[] = {  6,  0,  0,  0,  0, 48, 48, 48, 48, 48, 48, 48, 48,252,252, 48, 48, 60, 28,  0,  0,  0,  0}; /* "f" */
+static const GLubyte Helvetica18_Character_103[] = { 11, 28,  0,127,  0, 99,  0,  1,128, 61,128,127,128, 99,128,193,128,193,128,193,128,193,128, 97,128,127,128, 61,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "g" */
+static const GLubyte Helvetica18_Character_104[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0,195,  0,195,  0,195,  0,195,  0,195,  0,195,  0,195,  0,227,  0,223,  0,206,  0,192,  0,192,  0,192,  0,192,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "h" */
+static const GLubyte Helvetica18_Character_105[] = {  4,  0,  0,  0,  0,192,192,192,192,192,192,192,192,192,192,  0,  0,192,192,  0,  0,  0,  0}; /* "i" */
+static const GLubyte Helvetica18_Character_106[] = {  4,224,240, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,  0,  0, 48, 48,  0,  0,  0,  0}; /* "j" */
+static const GLubyte Helvetica18_Character_107[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0,199,  0,198,  0,206,  0,204,  0,216,  0,248,  0,240,  0,216,  0,204,  0,198,  0,192,  0,192,  0,192,  0,192,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "k" */
+static const GLubyte Helvetica18_Character_108[] = {  4,  0,  0,  0,  0,192,192,192,192,192,192,192,192,192,192,192,192,192,192,  0,  0,  0,  0}; /* "l" */
+static const GLubyte Helvetica18_Character_109[] = { 14,  0,  0,  0,  0,  0,  0,  0,  0,198, 48,198, 48,198, 48,198, 48,198, 48,198, 48,198, 48,231, 48,222,240,204, 96,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "m" */
+static const GLubyte Helvetica18_Character_110[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0,195,  0,195,  0,195,  0,195,  0,195,  0,195,  0,195,  0,227,  0,223,  0,206,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "n" */
+static const GLubyte Helvetica18_Character_111[] = { 11,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,127,  0, 99,  0,193,128,193,128,193,128,193,128, 99,  0,127,  0, 62,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "o" */
+static const GLubyte Helvetica18_Character_112[] = { 11,192,  0,192,  0,192,  0,192,  0,222,  0,255,  0,227,  0,193,128,193,128,193,128,193,128,227,  0,255,  0,222,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "p" */
+static const GLubyte Helvetica18_Character_113[] = { 11,  1,128,  1,128,  1,128,  1,128, 61,128,127,128, 99,128,193,128,193,128,193,128,193,128, 99,128,127,128, 61,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "q" */
+static const GLubyte Helvetica18_Character_114[] = {  6,  0,  0,  0,  0,192,192,192,192,192,192,192,224,216,216,  0,  0,  0,  0,  0,  0,  0,  0}; /* "r" */
+static const GLubyte Helvetica18_Character_115[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0,120,  0,252,  0,198,  0,  6,  0, 62,  0,252,  0,192,  0,198,  0,126,  0, 60,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "s" */
+static const GLubyte Helvetica18_Character_116[] = {  6,  0,  0,  0,  0, 24, 56, 48, 48, 48, 48, 48, 48,252,252, 48, 48, 48,  0,  0,  0,  0,  0}; /* "t" */
+static const GLubyte Helvetica18_Character_117[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0,115,  0,251,  0,199,  0,195,  0,195,  0,195,  0,195,  0,195,  0,195,  0,195,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "u" */
+static const GLubyte Helvetica18_Character_118[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0, 24,  0, 24,  0, 60,  0, 36,  0,102,  0,102,  0,102,  0,195,  0,195,  0,195,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "v" */
+static const GLubyte Helvetica18_Character_119[] = { 14,  0,  0,  0,  0,  0,  0,  0,  0, 25,128, 25,128, 57,192, 41, 64,105, 96,102, 96,102, 96,198, 48,198, 48,198, 48,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "w" */
+static const GLubyte Helvetica18_Character_120[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0,195,  0,231,  0,102,  0, 60,  0, 24,  0, 24,  0, 60,  0,102,  0,231,  0,195,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "x" */
+static const GLubyte Helvetica18_Character_121[] = { 10,112,  0,112,  0, 24,  0, 24,  0, 24,  0, 24,  0, 60,  0, 36,  0,102,  0,102,  0,102,  0,195,  0,195,  0,195,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "y" */
+static const GLubyte Helvetica18_Character_122[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0,254,  0,254,  0,192,  0, 96,  0, 48,  0, 24,  0, 12,  0,  6,  0,254,  0,254,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "z" */
+static const GLubyte Helvetica18_Character_065[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,192, 48,192, 48, 96, 96, 96, 96,127,224, 63,192, 48,192, 48,192, 25,128, 25,128, 15,  0, 15,  0,  6,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "A" */
+static const GLubyte Helvetica18_Character_066[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,255,128,255,192,192,224,192, 96,192, 96,192,224,255,192,255,128,193,128,192,192,192,192,193,192,255,128,255,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "B" */
+static const GLubyte Helvetica18_Character_067[] = { 14,  0,  0,  0,  0,  0,  0,  0,  0, 15,128, 63,224,112,112, 96, 48,224,  0,192,  0,192,  0,192,  0,192,  0,224,  0, 96, 48,112,112, 63,224, 15,128,  0,  0,  0,  0,  0,  0,  0,  0}; /* "C" */
+static const GLubyte Helvetica18_Character_068[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,255,  0,255,128,193,192,192,192,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192,192,193,192,255,128,255,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "D" */
+static const GLubyte Helvetica18_Character_069[] = { 11,  0,  0,  0,  0,  0,  0,  0,  0,255,128,255,128,192,  0,192,  0,192,  0,192,  0,255,  0,255,  0,192,  0,192,  0,192,  0,192,  0,255,128,255,128,  0,  0,  0,  0,  0,  0,  0,  0}; /* "E" */
+static const GLubyte Helvetica18_Character_070[] = { 11,  0,  0,  0,  0,  0,  0,  0,  0,192,  0,192,  0,192,  0,192,  0,192,  0,192,  0,255,  0,255,  0,192,  0,192,  0,192,  0,192,  0,255,128,255,128,  0,  0,  0,  0,  0,  0,  0,  0}; /* "F" */
+static const GLubyte Helvetica18_Character_071[] = { 14,  0,  0,  0,  0,  0,  0,  0,  0, 15,176, 63,240,112,112, 96, 48,224, 48,193,240,193,240,192,  0,192,  0,224, 48, 96, 48,112,112, 63,224, 15,128,  0,  0,  0,  0,  0,  0,  0,  0}; /* "G" */
+static const GLubyte Helvetica18_Character_072[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,255,224,255,224,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,  0,  0,  0,  0,  0,  0,  0,  0}; /* "H" */
+static const GLubyte Helvetica18_Character_073[] = {  6,  0,  0,  0,  0,192,192,192,192,192,192,192,192,192,192,192,192,192,192,  0,  0,  0,  0}; /* "I" */
+static const GLubyte Helvetica18_Character_074[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0, 60,  0,126,  0,231,  0,195,  0,195,  0,  3,  0,  3,  0,  3,  0,  3,  0,  3,  0,  3,  0,  3,  0,  3,  0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "J" */
+static const GLubyte Helvetica18_Character_075[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,192,112,192,224,193,192,195,128,199,  0,206,  0,252,  0,248,  0,220,  0,206,  0,199,  0,195,128,193,192,192,224,  0,  0,  0,  0,  0,  0,  0,  0}; /* "K" */
+static const GLubyte Helvetica18_Character_076[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0,255,  0,255,  0,192,  0,192,  0,192,  0,192,  0,192,  0,192,  0,192,  0,192,  0,192,  0,192,  0,192,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "L" */
+static const GLubyte Helvetica18_Character_077[] = { 16,  0,  0,  0,  0,  0,  0,  0,  0,195, 12,195, 12,199,140,196,140,204,204,204,204,216,108,216,108,240, 60,240, 60,224, 28,224, 28,192, 12,192, 12,  0,  0,  0,  0,  0,  0,  0,  0}; /* "M" */
+static const GLubyte Helvetica18_Character_078[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,192, 96,192,224,193,224,193,224,195, 96,198, 96,198, 96,204, 96,204, 96,216, 96,240, 96,240, 96,224, 96,192, 96,  0,  0,  0,  0,  0,  0,  0,  0}; /* "N" */
+static const GLubyte Helvetica18_Character_079[] = { 15,  0,  0,  0,  0,  0,  0,  0,  0, 15,128, 63,224,112,112, 96, 48,224, 56,192, 24,192, 24,192, 24,192, 24,224, 56, 96, 48,112,112, 63,224, 15,128,  0,  0,  0,  0,  0,  0,  0,  0}; /* "O" */
+static const GLubyte Helvetica18_Character_080[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,192,  0,192,  0,192,  0,192,  0,192,  0,192,  0,255,  0,255,128,193,192,192,192,192,192,193,192,255,128,255,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "P" */
+static const GLubyte Helvetica18_Character_081[] = { 15,  0,  0,  0,  0,  0,  0,  0, 48, 15,176, 63,224,112,240, 97,176,225,184,192, 24,192, 24,192, 24,192, 24,224, 56, 96, 48,112,112, 63,224, 15,128,  0,  0,  0,  0,  0,  0,  0,  0}; /* "Q" */
+static const GLubyte Helvetica18_Character_082[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,192,192,192,192,192,192,192,192,193,128,193,128,255,  0,255,128,193,192,192,192,192,192,193,192,255,128,255,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "R" */
+static const GLubyte Helvetica18_Character_083[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0, 63,  0,127,192,224,224,192, 96,  0, 96,  0,224,  3,192, 31,  0,124,  0,224,  0,192, 96,224,224,127,192, 31,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "S" */
+static const GLubyte Helvetica18_Character_084[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0, 12,  0, 12,  0, 12,  0, 12,  0, 12,  0, 12,  0, 12,  0, 12,  0, 12,  0, 12,  0, 12,  0, 12,  0,255,192,255,192,  0,  0,  0,  0,  0,  0,  0,  0}; /* "T" */
+static const GLubyte Helvetica18_Character_085[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0, 31,  0,127,192, 96,192,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,  0,  0,  0,  0,  0,  0,  0,  0}; /* "U" */
+static const GLubyte Helvetica18_Character_086[] = { 14,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0, 15,  0, 15,  0, 25,128, 25,128, 25,128, 48,192, 48,192, 48,192, 96, 96, 96, 96, 96, 96,192, 48,192, 48,  0,  0,  0,  0,  0,  0,  0,  0}; /* "V" */
+static const GLubyte Helvetica18_Character_087[] = { 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 24, 24,  0, 24, 24,  0, 28, 56,  0, 52, 44,  0, 54,108,  0, 54,108,  0,102,102,  0,102,102,  0, 98, 70,  0, 99,198,  0,195,195,  0,193,131,  0,193,131,  0,193,131,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "W" */
+static const GLubyte Helvetica18_Character_088[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,192, 96,224,224, 96,192,113,192, 49,128, 27,  0, 14,  0, 14,  0, 27,  0, 49,128,113,192, 96,192,224,224,192, 96,  0,  0,  0,  0,  0,  0,  0,  0}; /* "X" */
+static const GLubyte Helvetica18_Character_089[] = { 14,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  6,  0,  6,  0,  6,  0,  6,  0,  6,  0, 15,  0, 25,128, 48,192, 48,192, 96, 96, 96, 96,192, 48,192, 48,  0,  0,  0,  0,  0,  0,  0,  0}; /* "Y" */
+static const GLubyte Helvetica18_Character_090[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,255,192,255,192,192,  0, 96,  0, 48,  0, 24,  0, 28,  0, 12,  0,  6,  0,  3,  0,  1,128,  0,192,255,192,255,192,  0,  0,  0,  0,  0,  0,  0,  0}; /* "Z" */
+static const GLubyte Helvetica18_Character_048[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0, 60,  0,126,  0,102,  0,195,  0,195,  0,195,  0,195,  0,195,  0,195,  0,195,  0,102,  0,126,  0, 60,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "0" */
+static const GLubyte Helvetica18_Character_049[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0,248,  0,248,  0, 24,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "1" */
+static const GLubyte Helvetica18_Character_050[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0,255,  0,255,  0,192,  0,224,  0,112,  0, 56,  0, 28,  0, 14,  0,  7,  0,  3,  0,195,  0,254,  0, 60,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "2" */
+static const GLubyte Helvetica18_Character_051[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0, 60,  0,126,  0,199,  0,195,  0,  3,  0,  7,  0, 30,  0, 28,  0,  6,  0,195,  0,195,  0,126,  0, 60,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "3" */
+static const GLubyte Helvetica18_Character_052[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  3,  0,  3,  0,255,128,255,128,195,  0, 99,  0, 51,  0, 51,  0, 27,  0, 15,  0,  7,  0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "4" */
+static const GLubyte Helvetica18_Character_053[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0,124,  0,254,  0,199,  0,195,  0,  3,  0,  3,  0,199,  0,254,  0,252,  0,192,  0,192,  0,254,  0,254,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "5" */
+static const GLubyte Helvetica18_Character_054[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0, 60,  0,126,  0,227,  0,195,  0,195,  0,195,  0,254,  0,220,  0,192,  0,192,  0, 99,  0,127,  0, 60,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "6" */
+static const GLubyte Helvetica18_Character_055[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0, 96,  0, 96,  0, 48,  0, 48,  0, 48,  0, 24,  0, 24,  0, 12,  0, 12,  0,  6,  0,  3,  0,255,  0,255,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "7" */
+static const GLubyte Helvetica18_Character_056[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0, 60,  0,126,  0,231,  0,195,  0,195,  0,102,  0,126,  0,102,  0,195,  0,195,  0,231,  0,126,  0, 60,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "8" */
+static const GLubyte Helvetica18_Character_057[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0,124,  0,254,  0,198,  0,  3,  0,  3,  0, 59,  0,127,  0,195,  0,195,  0,195,  0,199,  0,126,  0, 60,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "9" */
+static const GLubyte Helvetica18_Character_096[] = {  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,192,192,128,128, 64,  0,  0,  0,  0}; /* "`" */
+static const GLubyte Helvetica18_Character_126[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,204,  0,126,  0, 51,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "~" */
+static const GLubyte Helvetica18_Character_033[] = {  6,  0,  0,  0,  0,192,192,  0,  0,128,128,192,192,192,192,192,192,192,192,  0,  0,  0,  0}; /* "!" */
+static const GLubyte Helvetica18_Character_064[] = { 18,  0,  0,  0,  7,224,  0, 31,240,  0, 56,  0,  0,112,  0,  0,103,112,  0,207,248,  0,204,204,  0,204,102,  0,204,102,  0,204, 99,  0,198, 51,  0,103,115,  0, 99,179,  0, 48,  6,  0, 28, 14,  0, 15,252,  0,  3,240,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "@" */
+static const GLubyte Helvetica18_Character_035[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0, 36,  0, 36,  0, 36,  0,255,128,255,128, 18,  0, 18,  0, 18,  0,127,192,127,192,  9,  0,  9,  0,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "#" */
+static const GLubyte Helvetica18_Character_036[] = { 10,  0,  0,  0,  0,  8,  0,  8,  0, 62,  0,127,  0,235,128,201,128,  9,128, 15,  0, 62,  0,120,  0,232,  0,200,  0,203,  0,127,  0, 62,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "$" */
+static const GLubyte Helvetica18_Character_037[] = { 16,  0,  0,  0,  0,  0,  0,  0,  0, 24,120, 24,252, 12,204, 12,204,  6,252,  6,120,  3,  0,123,  0,253,128,205,128,204,192,252,192,120, 96,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "%" */
+static const GLubyte Helvetica18_Character_094[] = {  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,130,  0,198,  0,108,  0, 56,  0, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "^" */
+static const GLubyte Helvetica18_Character_038[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0, 60,112,126,224,231,192,195,128,195,192,198,192,238,192,124,  0, 60,  0,102,  0,102,  0,126,  0, 60,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "&" */
+static const GLubyte Helvetica18_Character_042[] = {  7,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,136,112,112,248, 32, 32,  0,  0,  0,  0}; /* "*" */
+static const GLubyte Helvetica18_Character_040[] = {  6, 16, 48, 96, 96,192,192,192,192,192,192,192,192,192,192, 96, 96, 48, 16,  0,  0,  0,  0}; /* "(" */
+static const GLubyte Helvetica18_Character_041[] = {  6,128,192, 96, 96, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 96, 96,192,128,  0,  0,  0,  0}; /* ")" */
+static const GLubyte Helvetica18_Character_045[] = { 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,  0,255,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "-" */
+static const GLubyte Helvetica18_Character_095[] = { 10,255,248,255,248,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "_" */
+static const GLubyte Helvetica18_Character_061[] = { 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,254,  0,254,  0,  0,  0,  0,  0,254,  0,254,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "=" */
+static const GLubyte Helvetica18_Character_043[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0, 24,  0, 24,  0, 24,  0, 24,  0,255,  0,255,  0, 24,  0, 24,  0, 24,  0, 24,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "+" */
+static const GLubyte Helvetica18_Character_091[] = {  5,240,240,192,192,192,192,192,192,192,192,192,192,192,192,192,192,240,240,  0,  0,  0,  0}; /* "[" */
+static const GLubyte Helvetica18_Character_123[] = {  7, 12, 24, 48, 48, 48, 48, 48, 48, 96,192, 96, 48, 48, 48, 48, 48, 24, 12,  0,  0,  0,  0}; /* "{" */
+static const GLubyte Helvetica18_Character_125[] = {  7,192, 96, 48, 48, 48, 48, 48, 48, 24, 12, 24, 48, 48, 48, 48, 48, 96,192,  0,  0,  0,  0}; /* "}" */
+static const GLubyte Helvetica18_Character_093[] = {  5,240,240, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,240,240,  0,  0,  0,  0}; /* "]" */
+static const GLubyte Helvetica18_Character_059[] = {  5,  0,128, 64, 64,192,192,  0,  0,  0,  0,  0,  0,192,192,  0,  0,  0,  0,  0,  0,  0,  0}; /* ";" */
+static const GLubyte Helvetica18_Character_058[] = {  5,  0,  0,  0,  0,192,192,  0,  0,  0,  0,  0,  0,192,192,  0,  0,  0,  0,  0,  0,  0,  0}; /* ":" */
+static const GLubyte Helvetica18_Character_044[] = {  5,  0,128, 64, 64,192,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "," */
+static const GLubyte Helvetica18_Character_046[] = {  5,  0,  0,  0,  0,192,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "." */
+static const GLubyte Helvetica18_Character_060[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0, 15,  0, 60,  0,112,  0,192,  0,112,  0, 60,  0, 15,  0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "<" */
+static const GLubyte Helvetica18_Character_062[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0,192,  0,240,  0, 60,  0, 14,  0,  3,  0, 14,  0, 60,  0,240,  0,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* ">" */
+static const GLubyte Helvetica18_Character_047[] = {  5,  0,  0,  0,  0,192,192, 64, 64, 96, 96, 32, 32, 48, 48, 16, 16, 24, 24,  0,  0,  0,  0}; /* "/" */
+static const GLubyte Helvetica18_Character_063[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0, 48,  0, 48,  0,  0,  0,  0,  0, 48,  0, 48,  0, 48,  0, 56,  0, 28,  0, 14,  0,198,  0,198,  0,254,  0,124,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "?" */
+static const GLubyte Helvetica18_Character_092[] = {  5,  0,  0,  0,  0, 24, 24, 16, 16, 48, 48, 32, 32, 96, 96, 64, 64,192,192,  0,  0,  0,  0}; /* "\" */
+static const GLubyte Helvetica18_Character_034[] = {  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,144,144,216,216,216,  0,  0,  0,  0}; /* """ */
+
+/* Missing Characters filled in by John Fay by hand ... */
+static const GLubyte Helvetica18_Character_039[] = {  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,128, 64, 64,192,192,  0,  0,  0,  0}; /* "'" */
+static const GLubyte Helvetica18_Character_124[] = {  4, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96}; /* "|" */
+
+
+/* The font characters mapping: */
+static const GLubyte* Helvetica18_Character_Map[] = {Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_032,Helvetica18_Character_033,Helvetica18_Character_034,Helvetica18_Character_035,Helvetica18_Character_036,Helvetica18_Character_037,
+ Helvetica18_Character_038,Helvetica18_Character_039,Helvetica18_Character_040,Helvetica18_Character_041,Helvetica18_Character_042,Helvetica18_Character_043,Helvetica18_Character_044,Helvetica18_Character_045,Helvetica18_Character_046,Helvetica18_Character_047,Helvetica18_Character_048,Helvetica18_Character_049,Helvetica18_Character_050,Helvetica18_Character_051,Helvetica18_Character_052,Helvetica18_Character_053,Helvetica18_Character_054,Helvetica18_Character_055,Helvetica18_Character_056,Helvetica18_Character_057,Helvetica18_Character_058,Helvetica18_Character_059,Helvetica18_Character_060,Helvetica18_Character_061,Helvetica18_Character_062,Helvetica18_Character_063,Helvetica18_Character_064,Helvetica18_Character_065,Helvetica18_Character_066,Helvetica18_Character_067,Helvetica18_Character_068,Helvetica18_Character_069,Helvetica18_Character_070,Helvetica18_Character_071,Helvetica18_Character_072,Helvetica18_Character_073,Helvetica18_Character_074,Helvetica18_Character_075,Helvetica18_Character_076,
+ Helvetica18_Character_077,Helvetica18_Character_078,Helvetica18_Character_079,Helvetica18_Character_080,Helvetica18_Character_081,Helvetica18_Character_082,Helvetica18_Character_083,Helvetica18_Character_084,Helvetica18_Character_085,Helvetica18_Character_086,Helvetica18_Character_087,Helvetica18_Character_088,Helvetica18_Character_089,Helvetica18_Character_090,Helvetica18_Character_091,Helvetica18_Character_092,Helvetica18_Character_093,Helvetica18_Character_094,Helvetica18_Character_095,Helvetica18_Character_096,Helvetica18_Character_097,Helvetica18_Character_098,Helvetica18_Character_099,Helvetica18_Character_100,Helvetica18_Character_101,Helvetica18_Character_102,Helvetica18_Character_103,Helvetica18_Character_104,Helvetica18_Character_105,Helvetica18_Character_106,Helvetica18_Character_107,Helvetica18_Character_108,Helvetica18_Character_109,Helvetica18_Character_110,Helvetica18_Character_111,Helvetica18_Character_112,Helvetica18_Character_113,Helvetica18_Character_114,Helvetica18_Character_115,
+ Helvetica18_Character_116,Helvetica18_Character_117,Helvetica18_Character_118,Helvetica18_Character_119,Helvetica18_Character_120,Helvetica18_Character_121,Helvetica18_Character_122,Helvetica18_Character_123,Helvetica18_Character_124,Helvetica18_Character_125,Helvetica18_Character_126,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,
+ Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,
+ Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,
+ Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,Helvetica18_Character_042,NULL};
+
+/* The font structure: */
+const SFG_Font fgFontHelvetica18 = { "-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1", 93, 22, Helvetica18_Character_Map, -1.0f, 4.0f };
+
+static const GLubyte TimesRoman10_Character_032[] = {  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* " " */
+static const GLubyte TimesRoman10_Character_097[] = {  4,  0,  0,  0,224,160, 96, 32,192,  0,  0,  0,  0,  0}; /* "a" */
+static const GLubyte TimesRoman10_Character_098[] = {  5,  0,  0,  0,224,144,144,144,224,128,128,  0,  0,  0}; /* "b" */
+static const GLubyte TimesRoman10_Character_099[] = {  4,  0,  0,  0, 96,128,128,128, 96,  0,  0,  0,  0,  0}; /* "c" */
+static const GLubyte TimesRoman10_Character_100[] = {  5,  0,  0,  0,104,144,144,144,112, 16, 48,  0,  0,  0}; /* "d" */
+static const GLubyte TimesRoman10_Character_101[] = {  4,  0,  0,  0, 96,128,192,160, 96,  0,  0,  0,  0,  0}; /* "e" */
+static const GLubyte TimesRoman10_Character_102[] = {  4,  0,  0,  0,224, 64, 64, 64,224, 64, 48,  0,  0,  0}; /* "f" */
+static const GLubyte TimesRoman10_Character_103[] = {  5,  0,224,144, 96, 64,160,160,112,  0,  0,  0,  0,  0}; /* "g" */
+static const GLubyte TimesRoman10_Character_104[] = {  5,  0,  0,  0,216,144,144,144,224,128,128,  0,  0,  0}; /* "h" */
+static const GLubyte TimesRoman10_Character_105[] = {  3,  0,  0,  0, 64, 64, 64, 64,192,  0, 64,  0,  0,  0}; /* "i" */
+static const GLubyte TimesRoman10_Character_106[] = {  3,  0,128, 64, 64, 64, 64, 64,192,  0, 64,  0,  0,  0}; /* "j" */
+static const GLubyte TimesRoman10_Character_107[] = {  5,  0,  0,  0,152,144,224,160,144,128,128,  0,  0,  0}; /* "k" */
+static const GLubyte TimesRoman10_Character_108[] = {  4,  0,  0,  0,224, 64, 64, 64, 64, 64,192,  0,  0,  0}; /* "l" */
+static const GLubyte TimesRoman10_Character_109[] = {  8,  0,  0,  0,219,146,146,146,236,  0,  0,  0,  0,  0}; /* "m" */
+static const GLubyte TimesRoman10_Character_110[] = {  5,  0,  0,  0,216,144,144,144,224,  0,  0,  0,  0,  0}; /* "n" */
+static const GLubyte TimesRoman10_Character_111[] = {  5,  0,  0,  0, 96,144,144,144, 96,  0,  0,  0,  0,  0}; /* "o" */
+static const GLubyte TimesRoman10_Character_112[] = {  5,  0,192,128,224,144,144,144,224,  0,  0,  0,  0,  0}; /* "p" */
+static const GLubyte TimesRoman10_Character_113[] = {  5,  0, 56, 16,112,144,144,144,112,  0,  0,  0,  0,  0}; /* "q" */
+static const GLubyte TimesRoman10_Character_114[] = {  4,  0,  0,  0,224, 64, 64, 96,160,  0,  0,  0,  0,  0}; /* "r" */
+static const GLubyte TimesRoman10_Character_115[] = {  4,  0,  0,  0,224, 32, 96,128,224,  0,  0,  0,  0,  0}; /* "s" */
+static const GLubyte TimesRoman10_Character_116[] = {  4,  0,  0,  0, 48, 64, 64, 64,224, 64,  0,  0,  0,  0}; /* "t" */
+static const GLubyte TimesRoman10_Character_117[] = {  5,  0,  0,  0,104,144,144,144,144,  0,  0,  0,  0,  0}; /* "u" */
+static const GLubyte TimesRoman10_Character_118[] = {  5,  0,  0,  0, 32, 96, 80,144,216,  0,  0,  0,  0,  0}; /* "v" */
+static const GLubyte TimesRoman10_Character_119[] = {  8,  0,  0,  0, 40,108, 84,146,219,  0,  0,  0,  0,  0}; /* "w" */
+static const GLubyte TimesRoman10_Character_120[] = {  6,  0,  0,  0,216, 80, 32, 80,216,  0,  0,  0,  0,  0}; /* "x" */
+static const GLubyte TimesRoman10_Character_121[] = {  5,  0, 64, 64, 32, 48, 80, 72,220,  0,  0,  0,  0,  0}; /* "y" */
+static const GLubyte TimesRoman10_Character_122[] = {  5,  0,  0,  0,240,144, 64, 32,240,  0,  0,  0,  0,  0}; /* "z" */
+static const GLubyte TimesRoman10_Character_065[] = {  8,  0,  0,  0,238, 68,124, 40, 40, 56, 16,  0,  0,  0}; /* "A" */
+static const GLubyte TimesRoman10_Character_066[] = {  6,  0,  0,  0,240, 72, 72,112, 72, 72,240,  0,  0,  0}; /* "B" */
+static const GLubyte TimesRoman10_Character_067[] = {  7,  0,  0,  0,120,196,128,128,128,196,124,  0,  0,  0}; /* "C" */
+static const GLubyte TimesRoman10_Character_068[] = {  7,  0,  0,  0,248, 76, 68, 68, 68, 76,248,  0,  0,  0}; /* "D" */
+static const GLubyte TimesRoman10_Character_069[] = {  6,  0,  0,  0,248, 72, 64,112, 64, 72,248,  0,  0,  0}; /* "E" */
+static const GLubyte TimesRoman10_Character_070[] = {  6,  0,  0,  0,224, 64, 64,112, 64, 72,248,  0,  0,  0}; /* "F" */
+static const GLubyte TimesRoman10_Character_071[] = {  7,  0,  0,  0,120,196,132,156,128,196,124,  0,  0,  0}; /* "G" */
+static const GLubyte TimesRoman10_Character_072[] = {  8,  0,  0,  0,238, 68, 68,124, 68, 68,238,  0,  0,  0}; /* "H" */
+static const GLubyte TimesRoman10_Character_073[] = {  4,  0,  0,  0,224, 64, 64, 64, 64, 64,224,  0,  0,  0}; /* "I" */
+static const GLubyte TimesRoman10_Character_074[] = {  4,  0,  0,  0,192,160, 32, 32, 32, 32,112,  0,  0,  0}; /* "J" */
+static const GLubyte TimesRoman10_Character_075[] = {  7,  0,  0,  0,236, 72, 80, 96, 80, 72,236,  0,  0,  0}; /* "K" */
+static const GLubyte TimesRoman10_Character_076[] = {  6,  0,  0,  0,248, 72, 64, 64, 64, 64,224,  0,  0,  0}; /* "L" */
+static const GLubyte TimesRoman10_Character_077[] = { 10,  0,  0,  0,  0,  0,  0,235,128, 73,  0, 85,  0, 85,  0, 99,  0, 99,  0,227,128,  0,  0,  0,  0,  0,  0}; /* "M" */
+static const GLubyte TimesRoman10_Character_078[] = {  8,  0,  0,  0,228, 76, 76, 84, 84,100,238,  0,  0,  0}; /* "N" */
+static const GLubyte TimesRoman10_Character_079[] = {  7,  0,  0,  0,120,204,132,132,132,204,120,  0,  0,  0}; /* "O" */
+static const GLubyte TimesRoman10_Character_080[] = {  6,  0,  0,  0,224, 64, 64,112, 72, 72,240,  0,  0,  0}; /* "P" */
+static const GLubyte TimesRoman10_Character_081[] = {  7,  0, 12, 24,112,204,132,132,132,204,120,  0,  0,  0}; /* "Q" */
+static const GLubyte TimesRoman10_Character_082[] = {  7,  0,  0,  0,236, 72, 80,112, 72, 72,240,  0,  0,  0}; /* "R" */
+static const GLubyte TimesRoman10_Character_083[] = {  5,  0,  0,  0,224,144, 16, 96,192,144,112,  0,  0,  0}; /* "S" */
+static const GLubyte TimesRoman10_Character_084[] = {  6,  0,  0,  0,112, 32, 32, 32, 32,168,248,  0,  0,  0}; /* "T" */
+static const GLubyte TimesRoman10_Character_085[] = {  8,  0,  0,  0, 56,108, 68, 68, 68, 68,238,  0,  0,  0}; /* "U" */
+static const GLubyte TimesRoman10_Character_086[] = {  8,  0,  0,  0, 16, 16, 40, 40,108, 68,238,  0,  0,  0}; /* "V" */
+static const GLubyte TimesRoman10_Character_087[] = { 10,  0,  0,  0,  0,  0,  0, 34,  0, 34,  0, 85,  0, 85,  0,201,128,136,128,221,192,  0,  0,  0,  0,  0,  0}; /* "W" */
+static const GLubyte TimesRoman10_Character_088[] = {  8,  0,  0,  0,238, 68, 40, 16, 40, 68,238,  0,  0,  0}; /* "X" */
+static const GLubyte TimesRoman10_Character_089[] = {  8,  0,  0,  0, 56, 16, 16, 40, 40, 68,238,  0,  0,  0}; /* "Y" */
+static const GLubyte TimesRoman10_Character_090[] = {  6,  0,  0,  0,248,136, 64, 32, 16,136,248,  0,  0,  0}; /* "Z" */
+static const GLubyte TimesRoman10_Character_048[] = {  5,  0,  0,  0, 96,144,144,144,144,144, 96,  0,  0,  0}; /* "0" */
+static const GLubyte TimesRoman10_Character_049[] = {  5,  0,  0,  0,224, 64, 64, 64, 64,192, 64,  0,  0,  0}; /* "1" */
+static const GLubyte TimesRoman10_Character_050[] = {  5,  0,  0,  0,240, 64, 32, 32, 16,144, 96,  0,  0,  0}; /* "2" */
+static const GLubyte TimesRoman10_Character_051[] = {  5,  0,  0,  0,224, 16, 16, 96, 16,144, 96,  0,  0,  0}; /* "3" */
+static const GLubyte TimesRoman10_Character_052[] = {  5,  0,  0,  0, 16, 16,248,144, 80, 48, 16,  0,  0,  0}; /* "4" */
+static const GLubyte TimesRoman10_Character_053[] = {  5,  0,  0,  0,224,144, 16, 16,224, 64,112,  0,  0,  0}; /* "5" */
+static const GLubyte TimesRoman10_Character_054[] = {  5,  0,  0,  0, 96,144,144,144,224, 64, 48,  0,  0,  0}; /* "6" */
+static const GLubyte TimesRoman10_Character_055[] = {  5,  0,  0,  0, 64, 64, 64, 32, 32,144,240,  0,  0,  0}; /* "7" */
+static const GLubyte TimesRoman10_Character_056[] = {  5,  0,  0,  0, 96,144,144, 96,144,144, 96,  0,  0,  0}; /* "8" */
+static const GLubyte TimesRoman10_Character_057[] = {  5,  0,  0,  0,192, 32,112,144,144,144, 96,  0,  0,  0}; /* "9" */
+static const GLubyte TimesRoman10_Character_096[] = {  3,  0,  0,  0,  0,  0,  0,  0,  0,192,128,  0,  0,  0}; /* "`" */
+static const GLubyte TimesRoman10_Character_126[] = {  7,  0,  0,  0,  0,  0,152,100,  0,  0,  0,  0,  0,  0}; /* "~" */
+static const GLubyte TimesRoman10_Character_033[] = {  3,  0,  0,  0,128,  0,128,128,128,128,128,  0,  0,  0}; /* "!" */
+static const GLubyte TimesRoman10_Character_064[] = {  9,  0,  0, 62,  0, 64,  0,146,  0,173,  0,165,  0,165,  0,157,  0, 66,  0, 60,  0,  0,  0,  0,  0,  0,  0}; /* "@" */
+static const GLubyte TimesRoman10_Character_035[] = {  5,  0,  0,  0, 80, 80,248, 80,248, 80, 80,  0,  0,  0}; /* "#" */
+static const GLubyte TimesRoman10_Character_036[] = {  5,  0,  0, 32,224,144, 16, 96,128,144,112, 32,  0,  0}; /* "$" */
+static const GLubyte TimesRoman10_Character_037[] = {  8,  0,  0,  0, 68, 42, 42, 86,168,164,126,  0,  0,  0}; /* "%" */
+static const GLubyte TimesRoman10_Character_094[] = {  5,  0,  0,  0,  0,  0,  0,  0,160,160, 64,  0,  0,  0}; /* "^" */
+static const GLubyte TimesRoman10_Character_038[] = {  8,  0,  0,  0,118,141,152,116,110, 80, 48,  0,  0,  0}; /* "&" */
+static const GLubyte TimesRoman10_Character_042[] = {  5,  0,  0,  0,  0,  0,  0,  0,160, 64,160,  0,  0,  0}; /* "*" */
+static const GLubyte TimesRoman10_Character_040[] = {  4,  0, 32, 64, 64,128,128,128, 64, 64, 32,  0,  0,  0}; /* "(" */
+static const GLubyte TimesRoman10_Character_041[] = {  4,  0,128, 64, 64, 32, 32, 32, 64, 64,128,  0,  0,  0}; /* ")" */
+static const GLubyte TimesRoman10_Character_045[] = {  7,  0,  0,  0,  0,  0,240,  0,  0,  0,  0,  0,  0,  0}; /* "-" */
+static const GLubyte TimesRoman10_Character_095[] = {  5,252,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "_" */
+static const GLubyte TimesRoman10_Character_061[] = {  6,  0,  0,  0,  0,248,  0,248,  0,  0,  0,  0,  0,  0}; /* "=" */
+static const GLubyte TimesRoman10_Character_043[] = {  6,  0,  0,  0, 32, 32,248, 32, 32,  0,  0,  0,  0,  0}; /* "+" */
+static const GLubyte TimesRoman10_Character_091[] = {  3,  0,192,128,128,128,128,128,128,128,192,  0,  0,  0}; /* "[" */
+static const GLubyte TimesRoman10_Character_123[] = {  4,  0, 32, 64, 64, 64,128, 64, 64, 64, 32,  0,  0,  0}; /* "{" */
+static const GLubyte TimesRoman10_Character_125[] = {  4,  0,128, 64, 64, 64, 32, 64, 64, 64,128,  0,  0,  0}; /* "}" */
+static const GLubyte TimesRoman10_Character_093[] = {  3,  0,192, 64, 64, 64, 64, 64, 64, 64,192,  0,  0,  0}; /* "]" */
+static const GLubyte TimesRoman10_Character_059[] = {  3,  0,128,128,128,  0,  0,  0,128,  0,  0,  0,  0,  0}; /* ";" */
+static const GLubyte TimesRoman10_Character_058[] = {  3,  0,  0,  0,128,  0,  0,  0,128,  0,  0,  0,  0,  0}; /* ":" */
+static const GLubyte TimesRoman10_Character_044[] = {  3,  0,128,128,128,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "," */
+static const GLubyte TimesRoman10_Character_046[] = {  3,  0,  0,  0,128,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "." */
+static const GLubyte TimesRoman10_Character_060[] = {  5,  0,  0,  0, 32, 64,128, 64, 32,  0,  0,  0,  0,  0}; /* "<" */
+static const GLubyte TimesRoman10_Character_062[] = {  5,  0,  0,  0,128, 64, 32, 64,128,  0,  0,  0,  0,  0}; /* ">" */
+static const GLubyte TimesRoman10_Character_047[] = {  3,  0,  0,  0,128,128, 64, 64, 64, 32, 32,  0,  0,  0}; /* "/" */
+static const GLubyte TimesRoman10_Character_063[] = {  4,  0,  0,  0, 64,  0, 64, 64, 32,160,224,  0,  0,  0}; /* "?" */
+static const GLubyte TimesRoman10_Character_092[] = {  3,  0,  0,  0, 32, 32, 64, 64, 64,128,128,  0,  0,  0}; /* "\" */
+static const GLubyte TimesRoman10_Character_034[] = {  4,  0,  0,  0,  0,  0,  0,  0,  0,160,160,  0,  0,  0}; /* """ */
+
+/* Missing Characters filled in by John Fay by hand ... */
+static const GLubyte TimesRoman10_Character_039[] = {  3,  0,  0,  0,  0,  0,  0,  0,  0, 64, 64,192,  0,  0}; /* "'" */
+static const GLubyte TimesRoman10_Character_124[] = {  2,128,128,128,128,128,128,128,128,128,128,128,128,128}; /* "|" */
+
+
+/* The font characters mapping: */
+static const GLubyte* TimesRoman10_Character_Map[] = {TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_032,TimesRoman10_Character_033,TimesRoman10_Character_034,TimesRoman10_Character_035,
+TimesRoman10_Character_036,TimesRoman10_Character_037,TimesRoman10_Character_038,TimesRoman10_Character_039,TimesRoman10_Character_040,TimesRoman10_Character_041,TimesRoman10_Character_042,TimesRoman10_Character_043,TimesRoman10_Character_044,TimesRoman10_Character_045,TimesRoman10_Character_046,TimesRoman10_Character_047,TimesRoman10_Character_048,TimesRoman10_Character_049,TimesRoman10_Character_050,TimesRoman10_Character_051,TimesRoman10_Character_052,TimesRoman10_Character_053,TimesRoman10_Character_054,TimesRoman10_Character_055,TimesRoman10_Character_056,TimesRoman10_Character_057,TimesRoman10_Character_058,TimesRoman10_Character_059,TimesRoman10_Character_060,TimesRoman10_Character_061,TimesRoman10_Character_062,TimesRoman10_Character_063,TimesRoman10_Character_064,TimesRoman10_Character_065,TimesRoman10_Character_066,TimesRoman10_Character_067,TimesRoman10_Character_068,TimesRoman10_Character_069,TimesRoman10_Character_070,TimesRoman10_Character_071,TimesRoman10_Character_072,
+TimesRoman10_Character_073,TimesRoman10_Character_074,TimesRoman10_Character_075,TimesRoman10_Character_076,TimesRoman10_Character_077,TimesRoman10_Character_078,TimesRoman10_Character_079,TimesRoman10_Character_080,TimesRoman10_Character_081,TimesRoman10_Character_082,TimesRoman10_Character_083,TimesRoman10_Character_084,TimesRoman10_Character_085,TimesRoman10_Character_086,TimesRoman10_Character_087,TimesRoman10_Character_088,TimesRoman10_Character_089,TimesRoman10_Character_090,TimesRoman10_Character_091,TimesRoman10_Character_092,TimesRoman10_Character_093,TimesRoman10_Character_094,TimesRoman10_Character_095,TimesRoman10_Character_096,TimesRoman10_Character_097,TimesRoman10_Character_098,TimesRoman10_Character_099,TimesRoman10_Character_100,TimesRoman10_Character_101,TimesRoman10_Character_102,TimesRoman10_Character_103,TimesRoman10_Character_104,TimesRoman10_Character_105,TimesRoman10_Character_106,TimesRoman10_Character_107,TimesRoman10_Character_108,TimesRoman10_Character_109,
+TimesRoman10_Character_110,TimesRoman10_Character_111,TimesRoman10_Character_112,TimesRoman10_Character_113,TimesRoman10_Character_114,TimesRoman10_Character_115,TimesRoman10_Character_116,TimesRoman10_Character_117,TimesRoman10_Character_118,TimesRoman10_Character_119,TimesRoman10_Character_120,TimesRoman10_Character_121,TimesRoman10_Character_122,TimesRoman10_Character_123,TimesRoman10_Character_124,TimesRoman10_Character_125,TimesRoman10_Character_126,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,
+TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,
+TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,
+TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,TimesRoman10_Character_042,NULL};
+
+/* The font structure: */
+const SFG_Font fgFontTimesRoman10 = { "-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1", 93, 13, TimesRoman10_Character_Map, 0.0f, 3.0f };
+
+static const GLubyte TimesRoman24_Character_032[] = {  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* " " */
+static const GLubyte TimesRoman24_Character_097[] = { 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,113,128,251,  0,199,  0,195,  0,195,  0, 99,  0, 59,  0, 15,  0,  3,  0, 99,  0,103,  0, 62,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "a" */
+static const GLubyte TimesRoman24_Character_098[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 94,  0,115,128, 97,128, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 97,128,115,128,110,  0, 96,  0, 96,  0, 96,  0, 96,  0,224,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "b" */
+static const GLubyte TimesRoman24_Character_099[] = { 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30,  0,127,  0,112,128,224,  0,192,  0,192,  0,192,  0,192,  0,192,  0, 65,128, 99,128, 31,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "c" */
+static const GLubyte TimesRoman24_Character_100[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30,192,115,128, 97,128,193,128,193,128,193,128,193,128,193,128,193,128, 97,128,115,128, 29,128,  1,128,  1,128,  1,128,  1,128,  3,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "d" */
+static const GLubyte TimesRoman24_Character_101[] = { 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30,  0,127,  0,112,128,224,  0,192,  0,192,  0,192,  0,255,128,193,128, 65,128, 99,  0, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "e" */
+static const GLubyte TimesRoman24_Character_102[] = {  7,  0,  0,  0,  0,  0,  0,120, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,254, 48, 48, 48, 22, 14,  0,  0,  0,  0,  0}; /* "f" */
+static const GLubyte TimesRoman24_Character_103[] = { 12,  0,  0, 63,  0,241,192,192, 96,192, 32, 96, 96, 63,192,127,  0, 96,  0, 48,  0, 62,  0, 51,  0, 97,128, 97,128, 97,128, 97,128, 51,  0, 31,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "g" */
+static const GLubyte TimesRoman24_Character_104[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,241,224, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192,113,192,111,128,103,  0, 96,  0, 96,  0, 96,  0, 96,  0,224,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "h" */
+static const GLubyte TimesRoman24_Character_105[] = {  6,  0,  0,  0,  0,  0,  0,240, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,224,  0,  0,  0, 96, 96,  0,  0,  0,  0,  0}; /* "i" */
+static const GLubyte TimesRoman24_Character_106[] = {  6,  0,192,224, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,112,  0,  0,  0, 48, 48,  0,  0,  0,  0,  0}; /* "j" */
+static const GLubyte TimesRoman24_Character_107[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,243,224, 97,192, 99,128,103,  0,110,  0,108,  0,120,  0,104,  0,100,  0,102,  0, 99,  0,103,192, 96,  0, 96,  0, 96,  0, 96,  0,224,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "k" */
+static const GLubyte TimesRoman24_Character_108[] = {  6,  0,  0,  0,  0,  0,  0,240, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,224,  0,  0,  0,  0,  0}; /* "l" */
+static const GLubyte TimesRoman24_Character_109[] = { 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,241,227,192, 96,193,128, 96,193,128, 96,193,128, 96,193,128, 96,193,128, 96,193,128, 96,193,128, 96,193,128,113,227,128,111,159,  0,231, 14,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "m" */
+static const GLubyte TimesRoman24_Character_110[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,241,224, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192,113,192,111,128,231,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "n" */
+static const GLubyte TimesRoman24_Character_111[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30,  0,115,128, 97,128,192,192,192,192,192,192,192,192,192,192,192,192, 97,128,115,128, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "o" */
+static const GLubyte TimesRoman24_Character_112[] = { 12,  0,  0,240,  0, 96,  0, 96,  0, 96,  0, 96,  0,110,  0,115,128, 97,128, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 97,128,115,128,238,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "p" */
+static const GLubyte TimesRoman24_Character_113[] = { 12,  0,  0,  3,192,  1,128,  1,128,  1,128,  1,128, 29,128,115,128, 97,128,193,128,193,128,193,128,193,128,193,128,193,128, 97,128,115,128, 29,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "q" */
+static const GLubyte TimesRoman24_Character_114[] = {  8,  0,  0,  0,  0,  0,  0,240, 96, 96, 96, 96, 96, 96, 96, 96,118,110,230,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "r" */
+static const GLubyte TimesRoman24_Character_115[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,248,  0,198,  0,131,  0,  3,  0,  7,  0, 30,  0,124,  0,112,  0,224,  0,194,  0,102,  0, 62,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "s" */
+static const GLubyte TimesRoman24_Character_116[] = {  7,  0,  0,  0,  0,  0,  0, 28, 50, 48, 48, 48, 48, 48, 48, 48, 48, 48,254,112, 48, 16,  0,  0,  0,  0,  0,  0,  0}; /* "t" */
+static const GLubyte TimesRoman24_Character_117[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 28,224, 62,192,113,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192, 96,192,225,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "u" */
+static const GLubyte TimesRoman24_Character_118[] = { 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0, 14,  0, 14,  0, 26,  0, 25,  0, 25,  0, 49,  0, 48,128, 48,128, 96,128, 96,192,241,224,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "v" */
+static const GLubyte TimesRoman24_Character_119[] = { 17,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4, 16,  0, 14, 56,  0, 14, 56,  0, 26, 40,  0, 26,100,  0, 25,100,  0, 49,100,  0, 48,194,  0, 48,194,  0, 96,194,  0, 96,195,  0,241,231,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "w" */
+static const GLubyte TimesRoman24_Character_120[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,241,224, 96,192, 33,128, 51,128, 27,  0, 14,  0, 12,  0, 26,  0, 57,  0, 49,128, 96,192,241,224,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "x" */
+static const GLubyte TimesRoman24_Character_121[] = { 11,  0,  0,224,  0,240,  0, 24,  0,  8,  0, 12,  0,  4,  0, 14,  0, 14,  0, 26,  0, 25,  0, 25,  0, 49,  0, 48,128, 48,128, 96,128, 96,192,241,224,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "y" */
+static const GLubyte TimesRoman24_Character_122[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,  0,195,  0, 97,  0,112,  0, 48,  0, 56,  0, 24,  0, 28,  0, 14,  0,134,  0,195,  0,255,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "z" */
+static const GLubyte TimesRoman24_Character_065[] = { 17,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,252, 31,128, 48,  6,  0, 16,  6,  0, 16, 12,  0, 24, 12,  0,  8, 12,  0, 15,248,  0, 12, 24,  0,  4, 24,  0,  4, 48,  0,  6, 48,  0,  2, 48,  0,  2, 96,  0,  1, 96,  0,  1,192,  0,  1,192,  0,  0,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "A" */
+static const GLubyte TimesRoman24_Character_066[] = { 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,224, 48,120, 48, 24, 48, 12, 48, 12, 48, 12, 48, 24, 48, 56, 63,224, 48, 64, 48, 48, 48, 24, 48, 24, 48, 24, 48, 48, 48,112,255,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "B" */
+static const GLubyte TimesRoman24_Character_067[] = { 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,224, 30, 56, 56,  8, 96,  4, 96,  0,192,  0,192,  0,192,  0,192,  0,192,  0,192,  0,192,  0, 96,  4, 96,  4, 56, 12, 28, 60,  7,228,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "C" */
+static const GLubyte TimesRoman24_Character_068[] = { 17,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,192,  0, 48,112,  0, 48, 56,  0, 48, 12,  0, 48, 12,  0, 48,  6,  0, 48,  6,  0, 48,  6,  0, 48,  6,  0, 48,  6,  0, 48,  6,  0, 48,  6,  0, 48, 12,  0, 48, 12,  0, 48, 56,  0, 48,112,  0,255,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "D" */
+static const GLubyte TimesRoman24_Character_069[] = { 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,248, 48, 24, 48,  8, 48,  8, 48,  0, 48,  0, 48, 64, 48, 64, 63,192, 48, 64, 48, 64, 48,  0, 48,  0, 48, 16, 48, 16, 48, 48,255,240,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "E" */
+static const GLubyte TimesRoman24_Character_070[] = { 14,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,252,  0, 48,  0, 48,  0, 48,  0, 48,  0, 48,  0, 48, 32, 48, 32, 63,224, 48, 32, 48, 32, 48,  0, 48,  0, 48, 16, 48, 16, 48, 48,255,240,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "F" */
+static const GLubyte TimesRoman24_Character_071[] = { 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,224,  0, 30, 56,  0, 56, 28,  0, 96, 12,  0, 96, 12,  0,192, 12,  0,192, 12,  0,192, 63,  0,192,  0,  0,192,  0,  0,192,  0,  0,192,  0,  0, 96,  4,  0, 96,  4,  0, 56, 12,  0, 28, 60,  0,  7,228,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "G" */
+static const GLubyte TimesRoman24_Character_072[] = { 19,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,252, 31,128, 48,  6,  0, 48,  6,  0, 48,  6,  0, 48,  6,  0, 48,  6,  0, 48,  6,  0, 48,  6,  0, 63,254,  0, 48,  6,  0, 48,  6,  0, 48,  6,  0, 48,  6,  0, 48,  6,  0, 48,  6,  0, 48,  6,  0,252, 31,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "H" */
+static const GLubyte TimesRoman24_Character_073[] = {  8,  0,  0,  0,  0,  0,  0,252, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,252,  0,  0,  0,  0,  0}; /* "I" */
+static const GLubyte TimesRoman24_Character_074[] = { 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,120,  0,204,  0,198,  0,  6,  0,  6,  0,  6,  0,  6,  0,  6,  0,  6,  0,  6,  0,  6,  0,  6,  0,  6,  0,  6,  0,  6,  0,  6,  0, 31,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "J" */
+static const GLubyte TimesRoman24_Character_075[] = { 17,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,252, 31,  0, 48, 14,  0, 48, 28,  0, 48, 56,  0, 48,112,  0, 48,224,  0, 49,192,  0, 51,128,  0, 63,  0,  0, 62,  0,  0, 51,  0,  0, 49,128,  0, 48,192,  0, 48, 96,  0, 48, 48,  0, 48, 24,  0,252,126,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "K" */
+static const GLubyte TimesRoman24_Character_076[] = { 14,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,248, 48, 24, 48,  8, 48,  8, 48,  0, 48,  0, 48,  0, 48,  0, 48,  0, 48,  0, 48,  0, 48,  0, 48,  0, 48,  0, 48,  0, 48,  0,252,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "L" */
+static const GLubyte TimesRoman24_Character_077[] = { 22,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,248, 33,248, 32, 96, 96, 32, 96, 96, 32,208, 96, 32,208, 96, 33,136, 96, 33,136, 96, 35,  8, 96, 35,  4, 96, 38,  4, 96, 38,  2, 96, 44,  2, 96, 44,  2, 96, 56,  1, 96, 56,  1, 96, 48,  0,224,240,  0,248,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "M" */
+static const GLubyte TimesRoman24_Character_078[] = { 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,248, 12,  0, 32, 28,  0, 32, 28,  0, 32, 52,  0, 32,100,  0, 32,100,  0, 32,196,  0, 33,132,  0, 33,132,  0, 35,  4,  0, 38,  4,  0, 38,  4,  0, 44,  4,  0, 56,  4,  0, 56,  4,  0, 48,  4,  0,240, 31,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "N" */
+static const GLubyte TimesRoman24_Character_079[] = { 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,224,  0, 28, 56,  0, 56, 28,  0, 96,  6,  0, 96,  6,  0,192,  3,  0,192,  3,  0,192,  3,  0,192,  3,  0,192,  3,  0,192,  3,  0,192,  3,  0, 96,  6,  0, 96,  6,  0, 56, 28,  0, 28, 56,  0,  7,224,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "O" */
+static const GLubyte TimesRoman24_Character_080[] = { 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,252,  0, 48,  0, 48,  0, 48,  0, 48,  0, 48,  0, 48,  0, 48,  0, 63,192, 48,112, 48, 48, 48, 24, 48, 24, 48, 24, 48, 48, 48,112,255,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "P" */
+static const GLubyte TimesRoman24_Character_081[] = { 18,  0,  0,  0,  0, 15,  0,  0, 56,  0,  0,112,  0,  0,224,  0,  1,192,  0,  7,224,  0, 28, 56,  0, 56, 28,  0, 96,  6,  0, 96,  6,  0,192,  3,  0,192,  3,  0,192,  3,  0,192,  3,  0,192,  3,  0,192,  3,  0,192,  3,  0, 96,  6,  0, 96,  6,  0, 56, 28,  0, 28, 56,  0,  7,224,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "Q" */
+static const GLubyte TimesRoman24_Character_082[] = { 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,252, 30, 48, 28, 48, 56, 48,112, 48, 96, 48,192, 49,192, 51,128, 63,192, 48,112, 48, 48, 48, 56, 48, 24, 48, 56, 48, 48, 48,112,255,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "R" */
+static const GLubyte TimesRoman24_Character_083[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,158,  0,241,128,192,192,128, 96,128, 96,  0, 96,  0,224,  3,192, 15,128, 30,  0,120,  0,224,  0,192, 64,192, 64,192,192, 99,192, 30, 64,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "S" */
+static const GLubyte TimesRoman24_Character_084[] = { 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 15,192,  3,  0,  3,  0,  3,  0,  3,  0,  3,  0,  3,  0,  3,  0,  3,  0,  3,  0,  3,  0,  3,  0,  3,  0,131,  4,131,  4,195, 12,255,252,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "T" */
+static const GLubyte TimesRoman24_Character_085[] = { 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,224,  0, 28, 48,  0, 24,  8,  0, 48,  8,  0, 48,  4,  0, 48,  4,  0, 48,  4,  0, 48,  4,  0, 48,  4,  0, 48,  4,  0, 48,  4,  0, 48,  4,  0, 48,  4,  0, 48,  4,  0, 48,  4,  0, 48,  4,  0,252, 31,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "U" */
+static const GLubyte TimesRoman24_Character_086[] = { 17,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,128,  0,  1,128,  0,  1,128,  0,  3,192,  0,  3, 64,  0,  3, 96,  0,  6, 32,  0,  6, 32,  0,  6, 48,  0, 12, 16,  0, 12, 24,  0, 24,  8,  0, 24,  8,  0, 24, 12,  0, 48,  4,  0, 48,  6,  0,252, 31,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "V" */
+static const GLubyte TimesRoman24_Character_087[] = { 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,131,  0,  1,131,  0,  1,131,128,  3,135,128,  3, 70,128,  3, 70,192,  6, 70, 64,  6, 76, 64,  6, 76, 96, 12, 44, 96, 12, 44, 32, 24, 44, 32, 24, 24, 48, 24, 24, 16, 48, 24, 16, 48, 24, 24,252,126,126,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "W" */
+static const GLubyte TimesRoman24_Character_088[] = { 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,252, 15,192, 48,  3,128, 24,  7,  0,  8, 14,  0,  4, 12,  0,  6, 24,  0,  2, 56,  0,  1,112,  0,  0,224,  0,  0,192,  0,  1,192,  0,  3,160,  0,  3, 16,  0,  6,  8,  0, 14, 12,  0, 28,  6,  0,126, 15,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "X" */
+static const GLubyte TimesRoman24_Character_089[] = { 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,224,  1,128,  1,128,  1,128,  1,128,  1,128,  1,128,  3,192,  3, 64,  6, 96,  6, 32, 12, 48, 28, 16, 24, 24, 56,  8, 48, 12,252, 63,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "Y" */
+static const GLubyte TimesRoman24_Character_090[] = { 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,248,224, 24,112,  8, 48,  8, 56,  0, 24,  0, 28,  0, 14,  0,  6,  0,  7,  0,  3,  0,  3,128,  1,192,128,192,128,224,192,112,255,240,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "Z" */
+static const GLubyte TimesRoman24_Character_048[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30,  0, 51,  0, 97,128, 97,128,225,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, 97,128, 97,128, 51,  0, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "0" */
+static const GLubyte TimesRoman24_Character_049[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0,120,  0, 24,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "1" */
+static const GLubyte TimesRoman24_Character_050[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,128,255,192, 96, 64, 48,  0, 24,  0, 12,  0,  4,  0,  6,  0,  3,  0,  3,  0,  1,128,  1,128,129,128,129,128, 67,128,127,  0, 28,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "2" */
+static const GLubyte TimesRoman24_Character_051[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,120,  0,230,  0,195,  0,  1,  0,  1,128,  1,128,  1,128,  3,128,  7,  0, 30,  0, 12,  0,  6,  0,131,  0,131,  0, 71,  0,126,  0, 28,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "3" */
+static const GLubyte TimesRoman24_Character_052[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  3,  0,  3,  0,  3,  0,255,192,255,192,195,  0, 67,  0, 99,  0, 35,  0, 51,  0, 19,  0, 27,  0, 11,  0,  7,  0,  7,  0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "4" */
+static const GLubyte TimesRoman24_Character_053[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,126,  0,227,128,193,128,  0,192,  0,192,  0,192,  0,192,  1,192,  3,128, 15,128,126,  0,120,  0, 96,  0, 32,  0, 32,  0, 31,128, 31,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "5" */
+static const GLubyte TimesRoman24_Character_054[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30,  0,123,128, 97,128,224,192,192,192,192,192,192,192,192,192,193,128,243,128,238,  0, 96,  0,112,  0, 48,  0, 24,  0, 14,  0,  3,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "6" */
+static const GLubyte TimesRoman24_Character_055[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 24,  0, 24,  0, 12,  0, 12,  0, 12,  0,  4,  0,  6,  0,  6,  0,  2,  0,  3,  0,  3,  0,  1,  0,  1,128,129,128,192,192,255,192,127,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "7" */
+static const GLubyte TimesRoman24_Character_056[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30,  0,115,128,225,128,192,192,192,192,192,192, 65,192, 97,128, 55,  0, 30,  0, 30,  0, 51,  0, 97,128, 97,128, 97,128, 51,  0, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "8" */
+static const GLubyte TimesRoman24_Character_057[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,240,  0, 28,  0,  6,  0,  3,  0,  3,128,  1,128, 29,128,115,192, 97,192,192,192,192,192,192,192,192,192,193,192, 97,128,119,128, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "9" */
+static const GLubyte TimesRoman24_Character_096[] = {  7,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 96,224,128,192, 96,  0,  0,  0,  0,  0}; /* "`" */
+static const GLubyte TimesRoman24_Character_126[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,131,128,199,192,124, 96, 56, 32,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "~" */
+static const GLubyte TimesRoman24_Character_033[] = {  8,  0,  0,  0,  0,  0,  0,192,192,  0,  0,  0,192,192,192,192,192,192,192,192,192,192,192,192,  0,  0,  0,  0,  0}; /* "!" */
+static const GLubyte TimesRoman24_Character_064[] = { 22,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,240,  0, 14, 12,  0, 24,  0,  0, 48,  0,  0, 97,222,  0, 99,123,  0,198, 57,128,198, 24,128,198, 24,192,198, 24, 64,198, 12, 64,195, 12, 64,195,140, 64,225,252, 64, 96,236,192,112,  0,128, 56,  1,128, 28,  3,  0, 15, 14,  0,  3,248,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "@" */
+static const GLubyte TimesRoman24_Character_035[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 34,  0, 34,  0, 34,  0, 34,  0, 34,  0,255,192,255,192, 17,  0, 17,  0, 17,  0,127,224,127,224,  8,128,  8,128,  8,128,  8,128,  8,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "#" */
+static const GLubyte TimesRoman24_Character_036[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  4,  0, 63,  0,229,192,196,192,132, 96,132, 96,  4, 96,  4,224,  7,192,  7,128, 30,  0, 60,  0,116,  0,100,  0,100, 32,100, 96, 52,224, 31,128,  4,  0,  4,  0,  0,  0,  0,  0,  0,  0}; /* "$" */
+static const GLubyte TimesRoman24_Character_037[] = { 19,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 48, 60,  0, 24,114,  0, 12, 97,  0,  4, 96,128,  6, 96,128,  3, 48,128,  1, 25,128,  1,143,  0,120,192,  0,228, 64,  0,194, 96,  0,193, 48,  0,193, 16,  0, 97, 24,  0, 51,252,  0, 30, 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "%" */
+static const GLubyte TimesRoman24_Character_094[] = { 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,128,128,193,128, 65,  0, 99,  0, 34,  0, 54,  0, 20,  0, 28,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "^" */
+static const GLubyte TimesRoman24_Character_038[] = { 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 60, 60,  0,127,126,  0,225,225,  0,192,192,  0,193,192,  0,193,160,  0, 99, 32,  0, 55, 16,  0, 30, 24,  0, 14, 62,  0, 15,  0,  0, 29,128,  0, 24,192,  0, 24, 64,  0, 24, 64,  0, 12,192,  0,  7,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "&" */
+static const GLubyte TimesRoman24_Character_042[] = { 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  0, 28,  0,201,128,235,128, 28,  0,235,128,201,128, 28,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "*" */
+static const GLubyte TimesRoman24_Character_040[] = {  8,  0,  4,  8, 16, 48, 32, 96, 96,192,192,192,192,192,192,192,192, 96, 96, 32, 48, 16,  8,  4,  0,  0,  0,  0,  0}; /* "(" */
+static const GLubyte TimesRoman24_Character_041[] = {  8,  0,128, 64, 32, 48, 16, 24, 24, 12, 12, 12, 12, 12, 12, 12, 12, 24, 24, 16, 48, 32, 64,128,  0,  0,  0,  0,  0}; /* ")" */
+static const GLubyte TimesRoman24_Character_045[] = { 14,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,240,255,240,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "-" */
+static const GLubyte TimesRoman24_Character_095[] = { 13,  0,  0,255,248,255,248,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "_" */
+static const GLubyte TimesRoman24_Character_061[] = { 14,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,240,255,240,  0,  0,  0,  0,255,240,255,240,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "=" */
+static const GLubyte TimesRoman24_Character_043[] = { 14,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  6,  0,  6,  0,  6,  0,  6,  0,255,240,255,240,  6,  0,  6,  0,  6,  0,  6,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "+" */
+static const GLubyte TimesRoman24_Character_091[] = {  8,  0,  0,248,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,248,  0,  0,  0,  0,  0}; /* "[" */
+static const GLubyte TimesRoman24_Character_123[] = { 10,  0,  0,  7,  0, 12,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 16,  0, 48,  0, 32,  0,192,  0, 32,  0, 48,  0, 16,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 12,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "{" */
+static const GLubyte TimesRoman24_Character_125[] = { 10,  0,  0,224,  0, 48,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0,  8,  0, 12,  0,  4,  0,  3,  0,  4,  0, 12,  0,  8,  0, 24,  0, 24,  0, 24,  0, 24,  0, 24,  0, 48,  0,224,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "}" */
+static const GLubyte TimesRoman24_Character_093[] = {  8,  0,  0,248, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,248,  0,  0,  0,  0,  0}; /* "]" */
+static const GLubyte TimesRoman24_Character_059[] = {  7,  0,  0,  0,192, 96, 32,224,192,  0,  0,  0,  0,  0,  0,  0,192,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* ";" */
+static const GLubyte TimesRoman24_Character_058[] = {  6,  0,  0,  0,  0,  0,  0,192,192,  0,  0,  0,  0,  0,  0,  0,192,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* ":" */
+static const GLubyte TimesRoman24_Character_044[] = {  7,  0,  0,  0,192, 96, 32,224,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "," */
+static const GLubyte TimesRoman24_Character_046[] = {  6,  0,  0,  0,  0,  0,  0,192,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "." */
+static const GLubyte TimesRoman24_Character_060[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 96,  1,192,  7,  0, 28,  0,112,  0,192,  0,112,  0, 28,  0,  7,  0,  1,192,  0, 96,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "<" */
+static const GLubyte TimesRoman24_Character_062[] = { 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,192,  0,112,  0, 28,  0,  7,  0,  1,192,  0, 96,  1,192,  7,  0, 28,  0,112,  0,192,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* ">" */
+static const GLubyte TimesRoman24_Character_047[] = {  7,  0,  0,  0,192,192,192, 96, 96, 32, 48, 48, 16, 24, 24,  8, 12, 12,  4,  6,  6,  3,  3,  3,  0,  0,  0,  0,  0}; /* "/" */
+static const GLubyte TimesRoman24_Character_063[] = { 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 48,  0, 48,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 24,  0, 24,  0, 12,  0, 14,  0,  7,  0,195,  0,195,  0,131,  0,198,  0,124,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* "?" */
+static const GLubyte TimesRoman24_Character_092[] = {  7,  0,  0,  0,  0,  0,  0,  6,  6,  4, 12, 12,  8, 24, 24, 16, 48, 48, 32, 96, 96, 64,192,192,  0,  0,  0,  0,  0}; /* "\" */
+static const GLubyte TimesRoman24_Character_034[] = { 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,136,  0,204,  0,204,  0,204,  0,204,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}; /* """ */
+
+/* Missing Characters filled in by John Fay by hand ... */
+static const GLubyte TimesRoman24_Character_039[] = {  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,192, 96, 32,224,192,  0,  0,  0,  0,  0}; /* "'" */
+static const GLubyte TimesRoman24_Character_124[] = {  6, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,  0,  0}; /* "|" */
+
+
+/* The font characters mapping: */
+static const GLubyte* TimesRoman24_Character_Map[] = {TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_032,TimesRoman24_Character_033,TimesRoman24_Character_034,TimesRoman24_Character_035,
+TimesRoman24_Character_036,TimesRoman24_Character_037,TimesRoman24_Character_038,TimesRoman24_Character_039,TimesRoman24_Character_040,TimesRoman24_Character_041,TimesRoman24_Character_042,TimesRoman24_Character_043,TimesRoman24_Character_044,TimesRoman24_Character_045,TimesRoman24_Character_046,TimesRoman24_Character_047,TimesRoman24_Character_048,TimesRoman24_Character_049,TimesRoman24_Character_050,TimesRoman24_Character_051,TimesRoman24_Character_052,TimesRoman24_Character_053,TimesRoman24_Character_054,TimesRoman24_Character_055,TimesRoman24_Character_056,TimesRoman24_Character_057,TimesRoman24_Character_058,TimesRoman24_Character_059,TimesRoman24_Character_060,TimesRoman24_Character_061,TimesRoman24_Character_062,TimesRoman24_Character_063,TimesRoman24_Character_064,TimesRoman24_Character_065,TimesRoman24_Character_066,TimesRoman24_Character_067,TimesRoman24_Character_068,TimesRoman24_Character_069,TimesRoman24_Character_070,TimesRoman24_Character_071,TimesRoman24_Character_072,
+TimesRoman24_Character_073,TimesRoman24_Character_074,TimesRoman24_Character_075,TimesRoman24_Character_076,TimesRoman24_Character_077,TimesRoman24_Character_078,TimesRoman24_Character_079,TimesRoman24_Character_080,TimesRoman24_Character_081,TimesRoman24_Character_082,TimesRoman24_Character_083,TimesRoman24_Character_084,TimesRoman24_Character_085,TimesRoman24_Character_086,TimesRoman24_Character_087,TimesRoman24_Character_088,TimesRoman24_Character_089,TimesRoman24_Character_090,TimesRoman24_Character_091,TimesRoman24_Character_092,TimesRoman24_Character_093,TimesRoman24_Character_094,TimesRoman24_Character_095,TimesRoman24_Character_096,TimesRoman24_Character_097,TimesRoman24_Character_098,TimesRoman24_Character_099,TimesRoman24_Character_100,TimesRoman24_Character_101,TimesRoman24_Character_102,TimesRoman24_Character_103,TimesRoman24_Character_104,TimesRoman24_Character_105,TimesRoman24_Character_106,TimesRoman24_Character_107,TimesRoman24_Character_108,TimesRoman24_Character_109,
+TimesRoman24_Character_110,TimesRoman24_Character_111,TimesRoman24_Character_112,TimesRoman24_Character_113,TimesRoman24_Character_114,TimesRoman24_Character_115,TimesRoman24_Character_116,TimesRoman24_Character_117,TimesRoman24_Character_118,TimesRoman24_Character_119,TimesRoman24_Character_120,TimesRoman24_Character_121,TimesRoman24_Character_122,TimesRoman24_Character_123,TimesRoman24_Character_124,TimesRoman24_Character_125,TimesRoman24_Character_126,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,
+TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,
+TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,
+TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,TimesRoman24_Character_042,NULL};
+
+/* The font structure: */
+const SFG_Font fgFontTimesRoman24 = { "-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1", 93, 28, TimesRoman24_Character_Map, -1.0f, 6.0f };
+
+/*** END OF FILE ***/
+
diff --git a/src/freeglut_gamemode.c b/src/freeglut_gamemode.c
new file mode 100644 (file)
index 0000000..d6c6a25
--- /dev/null
@@ -0,0 +1,558 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-gamemode"
+
+#include "../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...
+ */
+void fghRememberState( void )
+{
+#if TARGET_HOST_UNIX_X11
+
+    /*
+     * This highly depends on the XFree86 extensions, not approved as X Consortium standards
+     */
+#   ifdef X_XF86VidModeGetModeLine
+
+    /*
+     * Query the current display settings:
+     */
+    XF86VidModeGetModeLine(
+        fgDisplay.Display,
+        fgDisplay.Screen,
+        &fgDisplay.DisplayModeClock,
+        &fgDisplay.DisplayMode
+    );
+
+#   else
+#       warning fghRememberState: missing XFree86 video mode extensions, game mode will not change screen resolution when activated
+#   endif
+
+#elif TARGET_HOST_WIN32
+
+/*    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
+ */
+void fghRestoreState( void )
+{
+#if TARGET_HOST_UNIX_X11
+
+    /*
+     * This highly depends on the XFree86 extensions, not approved as X Consortium standards
+     */
+#   ifdef X_XF86VidModeGetAllModeLines
+
+    XF86VidModeModeInfo** displayModes;
+    int i, displayModesCount;
+
+    /*
+     * Query for all the display available...
+     */
+    XF86VidModeGetAllModeLines(
+        fgDisplay.Display,
+        fgDisplay.Screen,
+        &displayModesCount,
+        &displayModes
+    );
+
+    /*
+     * Check every of the modes looking for one that matches our demands
+     */
+    for( i=0; i<displayModesCount; i++ )
+    {
+        if( displayModes[ i ]->hdisplay == fgDisplay.DisplayMode.hdisplay &&
+            displayModes[ i ]->vdisplay == fgDisplay.DisplayMode.vdisplay &&
+            displayModes[ i ]->dotclock == fgDisplay.DisplayModeClock )
+        {
+            /*
+             * OKi, this is the display mode we have been looking for...
+             */
+            XF86VidModeSwitchToMode(
+                fgDisplay.Display,
+                fgDisplay.Screen,
+                displayModes[ i ]
+            );
+
+           /*
+            * In case this will be the last X11 call we do before exit,
+            * we've to flush the X11 output queue to be sure the command
+            * is really brought onto it's way to the X server.
+            * The application should not do this because it
+            * would not be platform independent then.
+            */
+           XFlush(fgDisplay.Display);
+
+            return;
+        }
+    }
+
+#   else
+#       warning fghRestoreState: missing XFree86 video mode extensions, game mode will not change screen resolution when activated
+#   endif
+
+#elif TARGET_HOST_WIN32
+
+    /*
+     * Restore the previously rememebered desktop display settings
+     */
+    ChangeDisplaySettings( &fgDisplay.DisplayMode, 0 );
+
+#endif
+}
+
+/*
+ * Checks the display mode settings against user's preferences
+ */
+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) );
+}
+
+/*
+ * Changes the current display mode to match user's settings
+ */
+GLboolean fghChangeDisplayMode( GLboolean haveToTest )
+{
+#if TARGET_HOST_UNIX_X11
+
+    /*
+     * This highly depends on the XFree86 extensions, not approved as X Consortium standards
+     */
+#   ifdef X_XF86VidModeGetAllModeLines
+
+    XF86VidModeModeInfo** displayModes;
+    int i, displayModesCount;
+
+    /*
+     * Query for all the display available...
+     */
+    XF86VidModeGetAllModeLines(
+        fgDisplay.Display,
+        fgDisplay.Screen,
+        &displayModesCount,
+        &displayModes
+    );
+
+    /*
+     * Check every of the modes looking for one that matches our demands
+     */
+    for( i=0; i<displayModesCount; i++ )
+    {
+        if( fghCheckDisplayMode( displayModes[ i ]->hdisplay, displayModes[ i ]->vdisplay,
+                                 fgState.GameModeDepth, fgState.GameModeRefresh ) )
+        {
+           if( haveToTest )
+               return( TRUE );
+            /*
+             * OKi, this is the display mode we have been looking for...
+             */
+            XF86VidModeSwitchToMode(
+                fgDisplay.Display,
+                fgDisplay.Screen,
+                displayModes[ i ]
+            );
+
+            /*
+             * Set the viewport's origin to (0,0) (the game mode window's top-left corner)
+             */
+            XF86VidModeSetViewPort(
+                fgDisplay.Display,
+                fgDisplay.Screen,
+                0,
+                0
+            );
+
+            /*
+             * Return successfull...
+             */
+            return( TRUE );
+        }
+    }
+
+    /*
+     * Something must have went wrong
+     */
+    return( FALSE );
+
+#   else
+#       warning fghChangeDisplayMode: missing XFree86 video mode extensions, game mode will not change screen resolution when activated
+#   endif
+
+#elif TARGET_HOST_WIN32
+
+    unsigned int    displayModes = 0, mode = 0xffffffff;
+    GLboolean success = FALSE;
+/*    HDC      desktopDC; */
+    DEVMODE  devMode;
+
+    /*
+     * Enumerate the available display modes
+     * Try to get a complete match
+     */
+    while( EnumDisplaySettings( NULL, displayModes, &devMode ) == TRUE )
+    {
+        /*
+         * Does the enumerated display mode match the user's preferences?
+         */
+        if( fghCheckDisplayMode( devMode.dmPelsWidth,  devMode.dmPelsHeight,
+                                 devMode.dmBitsPerPel, devMode.dmDisplayFrequency ) )
+        {
+            /*
+             * OKi, we've found a matching display mode, remember its number and break
+             */
+            mode = displayModes;
+            break;
+        }
+
+        /*
+         * Switch to the next display mode, if any
+         */
+        displayModes++;
+    }
+
+    if ( mode == 0xffffffff )
+    {
+      /* then try without Display Frequency */
+      displayModes = 0;
+
+      /*
+       * Enumerate the available display modes
+       */
+      while( EnumDisplaySettings( NULL, displayModes, &devMode ) == TRUE )
+      {
+        /* then try without Display Frequency */
+
+        if( fghCheckDisplayMode( devMode.dmPelsWidth,  devMode.dmPelsHeight,
+                                 devMode.dmBitsPerPel, fgState.GameModeRefresh))
+        {
+          /*
+           * OKi, we've found a matching display mode, remember its number and break
+           */
+          mode = displayModes;
+          break;
+        }
+       
+        /*
+         * Switch to the next display mode, if any
+         */
+        displayModes++;
+      }
+    }
+
+    /*
+     * Did we find a matching display mode?
+     */
+    if( mode != 0xffffffff )
+    {
+        int retVal = DISP_CHANGE_SUCCESSFUL;
+
+        /*
+         * Mark the values we want to modify in the display change call
+         */
+        devMode.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
+
+        /*
+         * Change the current display mode (possibly in test mode only)
+         */
+        retVal = ChangeDisplaySettings( &devMode, haveToTest ? CDS_TEST : 0 );
+
+        /*
+         * I don't know if it's really needed, but looks nice:
+         */
+        success = (retVal == DISP_CHANGE_SUCCESSFUL) || (retVal == DISP_CHANGE_NOTUPDATED);
+
+        /*
+         * If it was not a test, remember the current screen settings
+         */
+        if( !haveToTest && success )
+        {
+            fgState.GameModeSize.X  = devMode.dmPelsWidth;
+            fgState.GameModeSize.Y  = devMode.dmPelsHeight;
+            fgState.GameModeDepth   = devMode.dmBitsPerPel;
+            fgState.GameModeRefresh = devMode.dmDisplayFrequency;
+        }
+    }
+
+    /*
+     * Otherwise we must have failed somewhere
+     */
+    return( success );
+
+#endif
+}
+
+
+/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
+
+/*
+ * Sets the game mode display string
+ */
+void FGAPIENTRY glutGameModeString( const char* string )
+{
+    int width = 640, height = 480, depth = 16, refresh = 72;
+
+    /*
+     * 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 )
+{
+    /*
+     * Check if a game mode window already exists...
+     */
+    if( fgStructure.GameMode != NULL )
+    {
+        /*
+         * ...if so, delete it before proceeding...
+         */
+        fgAddToWindowDestroyList( fgStructure.GameMode, TRUE );
+    }
+    else
+    {
+        /*
+         * ...otherwise remember the current resolution, etc.
+         */
+        fghRememberState();
+    }
+
+    /*
+     * We are ready to change the current screen's resolution now
+     */
+    if( fghChangeDisplayMode( FALSE ) == FALSE )
+    {
+             fgWarning( "failed to change screen settings" );
+        return( FALSE );
+    }
+
+    /*
+     * Finally, have the game mode window created
+     */
+    fgStructure.GameMode = fgCreateWindow( 
+        NULL, "FREEGLUT", 0, 0, fgState.GameModeSize.X, fgState.GameModeSize.Y, TRUE 
+    );
+
+#if TARGET_HOST_UNIX_X11
+
+    /*
+     * Move the mouse pointer over the game mode window
+     */
+    XSetInputFocus(
+        fgDisplay.Display,
+        fgStructure.GameMode->Window.Handle,
+        RevertToNone,
+        CurrentTime
+    );
+
+    /*
+     * Confine the mouse pointer to the window's client area
+     */
+    XGrabPointer(
+        fgDisplay.Display,
+        fgStructure.GameMode->Window.Handle,
+        TRUE,
+        ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|PointerMotionMask,
+        GrabModeAsync, GrabModeAsync,
+        fgStructure.GameMode->Window.Handle,
+        None,
+        CurrentTime
+    );
+
+    /*
+     * Grab the keyboard, too
+     */
+    XGrabKeyboard(
+        fgDisplay.Display,
+        fgStructure.GameMode->Window.Handle,
+        FALSE,
+        GrabModeAsync, GrabModeAsync,
+        CurrentTime
+    );
+
+#endif
+
+    /*
+     * Return successfull
+     */
+    return( TRUE );
+}
+
+/*
+ * Leaves the game mode
+ */
+void FGAPIENTRY glutLeaveGameMode( void )
+{
+    freeglut_return_if_fail( fgStructure.GameMode != NULL );
+
+    /*
+     * First of all, have the game mode window destroyed
+     */
+    fgAddToWindowDestroyList( fgStructure.GameMode, TRUE );
+
+#if TARGET_HOST_UNIX_X11
+
+    /*
+     * Ungrab the mouse and keyboard
+     */
+    XUngrabPointer( fgDisplay.Display, CurrentTime );
+    XUngrabKeyboard( fgDisplay.Display, CurrentTime );
+
+#endif
+
+    /*
+     * Then, have the desktop visual settings restored
+     */
+    fghRestoreState();
+}
+
+/*
+ * Returns information concerning the freeglut game mode
+ */
+int FGAPIENTRY glutGameModeGet( GLenum eWhat )
+{
+    /*
+     * See why are we bothered
+     */
+    switch( eWhat )
+    {
+    case GLUT_GAME_MODE_ACTIVE:
+        /*
+         * Check if the game mode is currently active
+         */
+        return( fgStructure.GameMode != NULL );
+
+    case GLUT_GAME_MODE_POSSIBLE:
+        /*
+         * Check if the current game mode settings are valid
+         */
+        return( fghChangeDisplayMode( TRUE ) );
+
+    case GLUT_GAME_MODE_WIDTH:
+        /*
+         * The game mode screen width
+         */
+        return( fgState.GameModeSize.X );
+
+    case GLUT_GAME_MODE_HEIGHT:
+        /*
+         * The game mode screen height
+         */
+        return( fgState.GameModeSize.Y );
+
+    case GLUT_GAME_MODE_PIXEL_DEPTH:
+        /*
+         * The game mode pixel depth
+         */
+        return( fgState.GameModeDepth );
+
+    case GLUT_GAME_MODE_REFRESH_RATE:
+        /*
+         * The 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 != NULL );
+    }
+
+    return( -1 );
+}
+
+/*** END OF FILE ***/
+
+
+
+
diff --git a/src/freeglut_geometry.c b/src/freeglut_geometry.c
new file mode 100644 (file)
index 0000000..23ba7d6
--- /dev/null
@@ -0,0 +1,1049 @@
+/*
+ * freeglut_geometry.c
+ *
+ * Freeglut geometry rendering 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-geometry"
+
+#include "../include/GL/freeglut.h"
+#include "freeglut_internal.h"
+
+/*
+ * TODO BEFORE THE STABLE RELEASE:
+ *
+ * Following functions have been contributed by Andreas Umbach.
+ *
+ *      glutWireCube()          -- looks OK
+ *      glutSolidCube()         -- OK
+ *      glutWireSphere()        -- OK
+ *      glutSolidSphere()       -- OK
+ *
+ * Following functions have been implemented by Pawel and modified by John Fay:
+ *
+ *      glutWireCone()          -- looks OK
+ *      glutSolidCone()         -- looks OK
+ *
+ * Those functions have been implemented by John Fay.
+ *
+ *      glutWireTorus()         -- looks OK
+ *      glutSolidTorus()        -- looks OK
+ *      glutWireDodecahedron()  -- looks OK
+ *      glutSolidDodecahedron() -- looks OK
+ *      glutWireOctahedron()    -- looks OK
+ *      glutSolidOctahedron()   -- looks OK
+ *      glutWireTetrahedron()   -- looks OK
+ *      glutSolidTetrahedron()  -- looks OK
+ *      glutWireIcosahedron()   -- looks OK
+ *      glutSolidIcosahedron()  -- looks OK
+ */
+
+
+/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
+
+/*
+ * Draws a wireframed cube. Code contributed by Andreas Umbach <marvin@dataway.ch>
+ */
+void FGAPIENTRY glutWireCube( GLdouble dSize )
+{
+    double size = dSize * 0.5;
+
+#   define V(a,b,c) glVertex3d( a size, b size, c size );
+#   define N(a,b,c) glNormal3d( a, b, c );
+
+    /*
+     * PWO: I dared to convert the code to use macros...
+     */
+    glBegin( GL_LINE_LOOP ); N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+); glEnd();
+    glBegin( GL_LINE_LOOP ); N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+); glEnd();
+    glBegin( GL_LINE_LOOP ); N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+); glEnd();
+    glBegin( GL_LINE_LOOP ); N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-); glEnd();
+    glBegin( GL_LINE_LOOP ); N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+); glEnd();
+    glBegin( GL_LINE_LOOP ); N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-); glEnd();
+
+#   undef V
+#   undef N
+}
+
+/*
+ * Draws a solid cube. Code contributed by Andreas Umbach <marvin@dataway.ch>
+ */
+void FGAPIENTRY glutSolidCube( GLdouble dSize )
+{
+    double size = dSize * 0.5;
+
+#   define V(a,b,c) glVertex3d( a size, b size, c size );
+#   define N(a,b,c) glNormal3d( a, b, c );
+
+    /*
+     * PWO: Again, I dared to convert the code to use macros...
+     */
+    glBegin( GL_QUADS );
+        N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+);
+        N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+);
+        N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+);
+        N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-);
+        N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+);
+        N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-);
+    glEnd();
+
+#   undef V
+#   undef N
+}
+
+/*
+ * Draws a wire sphere. Code contributed by Andreas Umbach <marvin@dataway.ch>
+ */
+void FGAPIENTRY glutWireSphere( GLdouble dRadius, GLint slices, GLint stacks )
+{
+    double  radius = dRadius, phi, psi, dpsi, dphi;
+    double *vertex;
+    int    i, j;
+    double cphi, sphi, cpsi, spsi ;
+
+    /*
+     * Allocate the vertices array
+     */
+    vertex = calloc( sizeof(double), 3 * slices * (stacks - 1) );
+
+    glPushMatrix();
+    glScaled( radius, radius, radius );
+
+    dpsi = M_PI / (stacks + 1);
+    dphi = 2 * M_PI / slices;
+    psi  = dpsi;
+
+    for( j=0; j<stacks-1; j++ )
+    {
+        cpsi = cos ( psi ) ;
+        spsi = sin ( psi ) ;
+        phi = 0.0;
+
+        for( i=0; i<slices; i++ )
+        {
+          int offset = 3 * ( j * slices + i ) ;
+          cphi = cos ( phi ) ;
+          sphi = sin ( phi ) ;
+            *(vertex + offset + 0) = sphi * spsi ;
+            *(vertex + offset + 1) = cphi * spsi ;
+            *(vertex + offset + 2) = cpsi ;
+            phi += dphi;
+        }
+
+        psi += dpsi;
+    }
+
+    for( i=0; i<slices; i++ )
+    {
+        glBegin( GL_LINE_STRIP );
+        glNormal3d( 0, 0, 1 );
+        glVertex3d( 0, 0, 1 );
+
+        for( j=0; j<stacks - 1; j++ )
+        {
+          int offset = 3 * ( j * slices + i ) ;
+            glNormal3dv( vertex + offset );
+            glVertex3dv( vertex + offset );
+        }
+
+        glNormal3d(0, 0, -1);
+        glVertex3d(0, 0, -1);
+        glEnd();
+    }
+
+    for( j=0; j<stacks-1; j++ )
+    {
+        glBegin(GL_LINE_LOOP);
+
+        for( i=0; i<slices; i++ )
+        {
+          int offset = 3 * ( j * slices + i ) ;
+            glNormal3dv( vertex + offset );
+            glVertex3dv( vertex + offset );
+        }
+
+        glEnd();
+    }
+
+    free( vertex );
+    glPopMatrix();
+}
+
+/*
+ * Draws a solid sphere. Code contributed by Andreas Umbach <marvin@dataway.ch>
+ */
+void FGAPIENTRY glutSolidSphere( GLdouble dRadius, GLint slices, GLint stacks )
+{
+    double  radius = dRadius, phi, psi, dpsi, dphi;
+    double *next, *tmp, *row;
+    int    i, j;
+    double cphi, sphi, cpsi, spsi ;
+
+    glPushMatrix();
+    /* glScalef( radius, radius, radius ); */
+
+    row  = calloc( sizeof(double), slices * 3 );
+    next = calloc( sizeof(double), slices * 3 );
+
+    dpsi = M_PI / (stacks + 1);
+    dphi = 2 * M_PI / slices;
+    psi  = dpsi;
+    phi  = 0;
+
+    /* init first line + do polar cap */
+    glBegin( GL_TRIANGLE_FAN );
+    glNormal3d( 0.0, 0.0, 1.0 );
+    glVertex3d( 0.0, 0.0, radius );
+
+    for( i=0; i<slices; i++ )
+    {
+        row[ i * 3 + 0 ] = sin( phi ) * sin( psi );
+        row[ i * 3 + 1 ] = cos( phi ) * sin( psi );
+        row[ i * 3 + 2 ] = cos( psi );
+
+        glNormal3dv( row + 3 * i );
+        glVertex3d(
+            radius * *(row + 3 * i + 0),
+            radius * *(row + 3 * i + 1),
+                 radius * *(row + 3 * i + 2)
+           );
+       
+        phi += dphi;
+    }
+
+    glNormal3dv( row );
+    glVertex3d( radius * *(row + 0), radius * *(row + 1), radius * *(row + 2) );
+    glEnd();
+
+    for( j=0; j<stacks-1; j++ )
+    {
+        phi = 0.0;
+        psi += dpsi;
+        cpsi = cos ( psi ) ;
+        spsi = sin ( psi ) ;
+
+        /* get coords */
+        glBegin( GL_QUAD_STRIP );
+
+        /* glBegin(GL_LINE_LOOP); */
+        for( i=0; i<slices; i++ )
+        {
+          cphi = cos ( phi ) ;
+          sphi = sin ( phi ) ;
+            next[ i * 3 + 0 ] = sphi * spsi ;
+            next[ i * 3 + 1 ] = cphi * spsi ;
+            next[ i * 3 + 2 ] = cpsi ;
+
+            glNormal3dv( row + i * 3 );
+            glVertex3d(
+                radius * *(row + 3 * i + 0),
+                radius * *(row + 3 * i + 1),
+                       radius * *(row + 3 * i + 2)
+                   );
+
+            glNormal3dv( next + i * 3 );
+            glVertex3d(
+                radius * *(next + 3 * i + 0),
+                radius * *(next + 3 * i + 1),
+                radius * *(next + 3 * i + 2)
+            );
+
+            phi += dphi;
+        }
+
+        glNormal3dv( row );
+        glVertex3d( radius * *(row + 0), radius * *(row + 1), radius * *(row + 2) );
+        glNormal3dv( next );
+        glVertex3d( radius * *(next + 0), radius * *(next + 1), radius * *(next + 2) );
+        glEnd();
+
+        tmp = row;
+        row = next;
+        next = tmp;
+    }
+
+    /* south pole */
+    glBegin( GL_TRIANGLE_FAN );
+    glNormal3d( 0.0, 0.0, -1.0 );
+    glVertex3d( 0.0, 0.0, -radius );
+    glNormal3dv( row );
+    glVertex3d( radius * *(row + 0), radius * *(row + 1), radius * *(row + 2) );
+
+    for( i=slices-1; i>=0; i-- )
+    {
+        glNormal3dv(row + 3 * i);
+        glVertex3d(
+            radius * *(row + 3 * i + 0),
+            radius * *(row + 3 * i + 1),
+                 radius * *(row + 3 * i + 2)
+          );
+    }
+
+    glEnd();
+
+    free(row);
+    free(next);
+    glPopMatrix();
+}
+
+/*
+ * Draws a wire cone
+ */
+void FGAPIENTRY glutWireCone( GLdouble base, GLdouble height, GLint slices, GLint stacks )
+{
+  double  alt   = height / (double) (stacks + 1);
+  double  angle = M_PI / (double) slices * 2.0;
+  double  slope = ( height / base );
+  double  sBase = base ;
+  double  sinNormal = ( base   / sqrt ( height * height + base * base )) ;
+  double  cosNormal = ( height / sqrt ( height * height + base * base )) ;
+
+  double *vertices = NULL;
+  int    i, j;
+
+  /*
+   * We need 'slices' points on a circle
+   */
+  vertices = calloc( sizeof(double), 2 * (slices + 1) );
+
+  for( j=0; j<slices+1; j++ )
+  {
+    vertices[ j*2 + 0 ] = cos( angle * j );
+    vertices[ j*2 + 1 ] = sin( angle * j );
+  }
+
+  /*
+   * First the cone's bottom...
+   */
+  for( j=0; j<slices; j++ )
+  {
+    glBegin( GL_LINE_LOOP );
+      glNormal3d( 0.0, 0.0, -1.0 );
+      glVertex3d( vertices[ (j+0)*2+0 ] * sBase, vertices[ (j+0)*2+1 ] * sBase, 0 );
+      glVertex3d( vertices[ (j+1)*2+0 ] * sBase, vertices[ (j+1)*2+1 ] * sBase, 0 );
+      glVertex3d( 0.0, 0.0, 0.0 );
+    glEnd();
+  }
+
+  /*
+   * Then all the stacks between the bottom and the top
+   */
+  for( i=0; i<stacks; i++ )
+  {
+    double alt_a = i * alt, alt_b = (i + 1) * alt;
+    double scl_a = (height - alt_a) / slope;
+    double scl_b = (height - alt_b) / slope;
+
+    for( j=0; j<slices; j++ )
+    {
+      glBegin( GL_LINE_LOOP );
+        glNormal3d( sinNormal * vertices[(j+0)*2+0], sinNormal * vertices[(j+0)*2+1], cosNormal ) ;
+        glVertex3d( vertices[(j+0)*2+0] * scl_a, vertices[(j+0)*2+1] * scl_a, alt_a );
+        glNormal3d( sinNormal * vertices[(j+1)*2+0], sinNormal * vertices[(j+1)*2+1], cosNormal ) ;
+        glVertex3d( vertices[(j+1)*2+0] * scl_a, vertices[(j+1)*2+1] * scl_a, alt_a );
+        glNormal3d( sinNormal * vertices[(j+0)*2+0], sinNormal * vertices[(j+0)*2+1], cosNormal ) ;
+        glVertex3d( vertices[(j+0)*2+0] * scl_b, vertices[(j+0)*2+1] * scl_b, alt_b );
+      glEnd();
+
+      glBegin( GL_LINE_LOOP );
+        glNormal3d( sinNormal * vertices[(j+0)*2+0], sinNormal * vertices[(j+0)*2+1], cosNormal ) ;
+        glVertex3d( vertices[(j+0)*2+0] * scl_b, vertices[(j+0)*2+1] * scl_b, alt_b );
+        glNormal3d( sinNormal * vertices[(j+1)*2+0], sinNormal * vertices[(j+1)*2+1], cosNormal ) ;
+        glVertex3d( vertices[(j+1)*2+0] * scl_b, vertices[(j+1)*2+1] * scl_b, alt_b );
+        glVertex3d( vertices[(j+1)*2+0] * scl_a, vertices[(j+1)*2+1] * scl_a, alt_a );
+      glEnd();
+    }
+  }
+
+  /*
+   * Finally have the top part drawn...
+   */
+  for( j=0; j<slices; j++ )
+  {
+    double scl = alt / slope;
+
+    glBegin( GL_LINE_LOOP );
+      glNormal3d( sinNormal * vertices[(j+0)*2+0], sinNormal * vertices[(j+0)*2+1], cosNormal ) ;
+      glVertex3d( vertices[ (j+0)*2+0 ] * scl, vertices[ (j+0)*2+1 ] * scl, height - alt );
+      glNormal3d( sinNormal * vertices[(j+1)*2+0], sinNormal * vertices[(j+1)*2+1], cosNormal ) ;
+      glVertex3d( vertices[ (j+1)*2+0 ] * scl, vertices[ (j+1)*2+1 ] * scl, height - alt );
+      glVertex3d( 0, 0, height );
+    glEnd();
+  }
+}
+
+/*
+ * Draws a solid cone
+ */
+void FGAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLint stacks )
+{
+  double  alt   = height / (double) (stacks + 1);
+  double  angle = M_PI / (double) slices * 2.0f;
+  double  slope = ( height / base );
+  double  sBase = base ;
+  double  sinNormal = ( base   / sqrt ( height * height + base * base )) ;
+  double  cosNormal = ( height / sqrt ( height * height + base * base )) ;
+
+  double *vertices = NULL;
+  int    i, j;
+
+  /*
+   * We need 'slices' points on a circle
+   */
+  vertices = calloc( sizeof(double), 2 * (slices + 1) );
+
+  for( j=0; j<slices+1; j++ )
+  {
+    vertices[ j*2 + 0 ] = cos( angle * j );
+    vertices[ j*2 + 1 ] = sin( angle * j );
+  }
+
+  /*
+   * First the cone's bottom...
+   */
+  for( j=0; j<slices; j++ )
+  {
+    double scl = height / slope;
+
+    glBegin( GL_TRIANGLES );
+      glNormal3d( 0.0, 0.0, -1.0 );
+      glVertex3d( vertices[ (j+0)*2+0 ] * sBase, vertices[ (j+0)*2+1 ] * sBase, 0 );
+      glVertex3d( vertices[ (j+1)*2+0 ] * sBase, vertices[ (j+1)*2+1 ] * sBase, 0 );
+      glVertex3d( 0.0, 0.0, 0.0 );
+    glEnd();
+  }
+
+  /*
+   * Then all the stacks between the bottom and the top
+   */
+  for( i=0; i<stacks; i++ )
+  {
+    double alt_a = i * alt, alt_b = (i + 1) * alt;
+    double scl_a = (height - alt_a) / slope;
+    double scl_b = (height - alt_b) / slope;
+
+    for( j=0; j<slices; j++ )
+    {
+      glBegin( GL_TRIANGLES );
+        glNormal3d( sinNormal * vertices[(j+0)*2+0], sinNormal * vertices[(j+0)*2+1], cosNormal ) ;
+        glVertex3d( vertices[(j+0)*2+0] * scl_a, vertices[(j+0)*2+1] * scl_a, alt_a );
+        glNormal3d( sinNormal * vertices[(j+1)*2+0], sinNormal * vertices[(j+1)*2+1], cosNormal ) ;
+        glVertex3d( vertices[(j+1)*2+0] * scl_a, vertices[(j+1)*2+1] * scl_a, alt_a );
+        glNormal3d( sinNormal * vertices[(j+0)*2+0], sinNormal * vertices[(j+0)*2+1], cosNormal ) ;
+        glVertex3d( vertices[(j+0)*2+0] * scl_b, vertices[(j+0)*2+1] * scl_b, alt_b );
+      glEnd();
+
+      glBegin( GL_TRIANGLES );
+        glNormal3d( sinNormal * vertices[(j+0)*2+0], sinNormal * vertices[(j+0)*2+1], cosNormal ) ;
+        glVertex3d( vertices[(j+0)*2+0] * scl_b, vertices[(j+0)*2+1] * scl_b, alt_b );
+        glNormal3d( sinNormal * vertices[(j+1)*2+0], sinNormal * vertices[(j+1)*2+1], cosNormal ) ;
+        glVertex3d( vertices[(j+1)*2+0] * scl_b, vertices[(j+1)*2+1] * scl_b, alt_b );
+        glVertex3d( vertices[(j+1)*2+0] * scl_a, vertices[(j+1)*2+1] * scl_a, alt_a );
+      glEnd();
+    }
+  }
+
+  /*
+   * Finally have the top part drawn...
+   */
+  for( j=0; j<slices; j++ )
+  {
+    double scl = alt / slope;
+
+    glBegin( GL_TRIANGLES );
+      glNormal3d( sinNormal * vertices[(j+0)*2+0], sinNormal * vertices[(j+0)*2+1], cosNormal ) ;
+      glVertex3d( vertices[ (j+0)*2+0 ] * scl, vertices[ (j+0)*2+1 ] * scl, height - alt );
+      glNormal3d( sinNormal * vertices[(j+1)*2+0], sinNormal * vertices[(j+1)*2+1], cosNormal ) ;
+      glVertex3d( vertices[ (j+1)*2+0 ] * scl, vertices[ (j+1)*2+1 ] * scl, height - alt );
+      glVertex3d( 0, 0, height );
+    glEnd();
+  }
+}
+
+/*
+ *
+ */
+void FGAPIENTRY glutWireTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GLint nSides, GLint nRings )
+{
+  double  iradius = dInnerRadius, oradius = dOuterRadius, phi, psi, dpsi, dphi;
+  double *vertex, *normal;
+  int    i, j;
+  double spsi, cpsi, sphi, cphi ;
+
+  /*
+   * Allocate the vertices array
+   */
+  vertex = calloc( sizeof(double), 3 * nSides * nRings );
+  normal = calloc( sizeof(double), 3 * nSides * nRings );
+
+  glPushMatrix();
+
+  dpsi = 2.0 * M_PI / (double)nRings ;
+  dphi = 2.0 * M_PI / (double)nSides ;
+  psi  = 0.0;
+
+  for( j=0; j<nRings; j++ )
+  {
+    cpsi = cos ( psi ) ;
+    spsi = sin ( psi ) ;
+    phi = 0.0;
+
+    for( i=0; i<nSides; i++ )
+    {
+      int offset = 3 * ( j * nSides + i ) ;
+      cphi = cos ( phi ) ;
+      sphi = sin ( phi ) ;
+      *(vertex + offset + 0) = cpsi * ( oradius + cphi * iradius ) ;
+      *(vertex + offset + 1) = spsi * ( oradius + cphi * iradius ) ;
+      *(vertex + offset + 2) =                    sphi * iradius   ;
+      *(normal + offset + 0) = cpsi * cphi ;
+      *(normal + offset + 1) = spsi * cphi ;
+      *(normal + offset + 2) =        sphi ;
+      phi += dphi;
+    }
+
+    psi += dpsi;
+  }
+
+  for( i=0; i<nSides; i++ )
+  {
+    glBegin( GL_LINE_LOOP );
+
+    for( j=0; j<nRings; j++ )
+    {
+      int offset = 3 * ( j * nSides + i ) ;
+      glNormal3dv( normal + offset );
+      glVertex3dv( vertex + offset );
+    }
+
+    glEnd();
+  }
+
+  for( j=0; j<nRings; j++ )
+  {
+    glBegin(GL_LINE_LOOP);
+
+    for( i=0; i<nSides; i++ )
+    {
+      int offset = 3 * ( j * nSides + i ) ;
+      glNormal3dv( normal + offset );
+      glVertex3dv( vertex + offset );
+    }
+
+    glEnd();
+  }
+
+  free ( vertex ) ;
+  free ( normal ) ;
+  glPopMatrix();
+}
+
+/*
+ *
+ */
+void FGAPIENTRY glutSolidTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GLint nSides, GLint nRings )
+{
+  double  iradius = dInnerRadius, oradius = dOuterRadius, phi, psi, dpsi, dphi;
+  double *vertex, *normal;
+  int    i, j;
+  double spsi, cpsi, sphi, cphi ;
+
+  /*
+   * Increment the number of sides and rings to allow for one more point than surface
+   */
+  nSides ++ ;
+  nRings ++ ;
+
+  /*
+   * Allocate the vertices array
+   */
+  vertex = calloc( sizeof(double), 3 * nSides * nRings );
+  normal = calloc( sizeof(double), 3 * nSides * nRings );
+
+  glPushMatrix();
+
+  dpsi = 2.0 * M_PI / (double)(nRings - 1) ;
+  dphi = 2.0 * M_PI / (double)(nSides - 1) ;
+  psi  = 0.0;
+
+  for( j=0; j<nRings; j++ )
+  {
+    cpsi = cos ( psi ) ;
+    spsi = sin ( psi ) ;
+    phi = 0.0;
+
+    for( i=0; i<nSides; i++ )
+    {
+      int offset = 3 * ( j * nSides + i ) ;
+      cphi = cos ( phi ) ;
+      sphi = sin ( phi ) ;
+      *(vertex + offset + 0) = cpsi * ( oradius + cphi * iradius ) ;
+      *(vertex + offset + 1) = spsi * ( oradius + cphi * iradius ) ;
+      *(vertex + offset + 2) =                    sphi * iradius   ;
+      *(normal + offset + 0) = cpsi * cphi ;
+      *(normal + offset + 1) = spsi * cphi ;
+      *(normal + offset + 2) =        sphi ;
+      phi += dphi;
+    }
+
+    psi += dpsi;
+  }
+
+    glBegin( GL_QUADS );
+  for( i=0; i<nSides-1; i++ )
+  {
+    for( j=0; j<nRings-1; j++ )
+    {
+      int offset = 3 * ( j * nSides + i ) ;
+      glNormal3dv( normal + offset );
+      glVertex3dv( vertex + offset );
+      glNormal3dv( normal + offset + 3 );
+      glVertex3dv( vertex + offset + 3 );
+      glNormal3dv( normal + offset + 3 * nSides + 3 );
+      glVertex3dv( vertex + offset + 3 * nSides + 3 );
+      glNormal3dv( normal + offset + 3 * nSides );
+      glVertex3dv( vertex + offset + 3 * nSides );
+    }
+  }
+
+  glEnd();
+
+  free ( vertex ) ;
+  free ( normal ) ;
+  glPopMatrix();
+}
+
+/*
+ *
+ */
+void FGAPIENTRY glutWireDodecahedron( void )
+{
+  /* Magic Numbers:  It is possible to create a dodecahedron by attaching two pentagons to each face of
+   * of a cube.  The coordinates of the points are:
+   *   (+-x,0, z); (+-1, 1, 1); (0, z, x )
+   * where x = 0.61803398875 and z = 1.61803398875.
+   */
+  glBegin ( GL_LINE_LOOP ) ;
+  glNormal3d (  0.0,  0.525731112119,  0.850650808354 ) ; glVertex3d (  0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( -0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d (  0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_LINE_LOOP ) ;
+  glNormal3d (  0.0,  0.525731112119, -0.850650808354 ) ; glVertex3d (  0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d (  0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_LINE_LOOP ) ;
+  glNormal3d (  0.0, -0.525731112119,  0.850650808354 ) ; glVertex3d (  0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d (  0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_LINE_LOOP ) ;
+  glNormal3d (  0.0, -0.525731112119, -0.850650808354 ) ; glVertex3d (  0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d (  0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
+  glEnd () ;
+
+  glBegin ( GL_LINE_LOOP ) ;
+  glNormal3d (  0.850650808354,  0.0,  0.525731112119 ) ; glVertex3d (  0.61803398875,  0.0,  1.61803398875 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d (  1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d (  1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_LINE_LOOP ) ;
+  glNormal3d ( -0.850650808354,  0.0,  0.525731112119 ) ; glVertex3d ( -0.61803398875,  0.0,  1.61803398875 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_LINE_LOOP ) ;
+  glNormal3d (  0.850650808354,  0.0, -0.525731112119 ) ; glVertex3d (  0.61803398875,  0.0, -1.61803398875 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d (  1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d (  1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_LINE_LOOP ) ;
+  glNormal3d ( -0.850650808354,  0.0, -0.525731112119 ) ; glVertex3d ( -0.61803398875,  0.0, -1.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
+  glEnd () ;
+
+  glBegin ( GL_LINE_LOOP ) ;
+  glNormal3d (  0.525731112119,  0.850650808354,  0.0 ) ; glVertex3d (  1.61803398875,  0.61803398875,  0.0 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d ( 0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_LINE_LOOP ) ;
+  glNormal3d (  0.525731112119, -0.850650808354,  0.0 ) ; glVertex3d (  1.61803398875, -0.61803398875,  0.0 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d ( 0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_LINE_LOOP ) ;
+  glNormal3d ( -0.525731112119,  0.850650808354,  0.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875,  0.0 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( 0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d ( 0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_LINE_LOOP ) ;
+  glNormal3d ( -0.525731112119, -0.850650808354,  0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875,  0.0 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
+  glEnd () ;
+}
+
+/*
+ *
+ */
+void FGAPIENTRY glutSolidDodecahedron( void )
+{
+  /* Magic Numbers:  It is possible to create a dodecahedron by attaching two pentagons to each face of
+   * of a cube.  The coordinates of the points are:
+   *   (+-x,0, z); (+-1, 1, 1); (0, z, x )
+   * where x = 0.61803398875 and z = 1.61803398875.
+   */
+  glBegin ( GL_POLYGON ) ;
+  glNormal3d (  0.0,  0.525731112119,  0.850650808354 ) ; glVertex3d (  0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( -0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d (  0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_POLYGON ) ;
+  glNormal3d (  0.0,  0.525731112119, -0.850650808354 ) ; glVertex3d (  0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d (  0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_POLYGON ) ;
+  glNormal3d (  0.0, -0.525731112119,  0.850650808354 ) ; glVertex3d (  0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d (  0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_POLYGON ) ;
+  glNormal3d (  0.0, -0.525731112119, -0.850650808354 ) ; glVertex3d (  0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d (  0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
+  glEnd () ;
+
+  glBegin ( GL_POLYGON ) ;
+  glNormal3d (  0.850650808354,  0.0,  0.525731112119 ) ; glVertex3d (  0.61803398875,  0.0,  1.61803398875 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d (  1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d (  1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_POLYGON ) ;
+  glNormal3d ( -0.850650808354,  0.0,  0.525731112119 ) ; glVertex3d ( -0.61803398875,  0.0,  1.61803398875 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_POLYGON ) ;
+  glNormal3d (  0.850650808354,  0.0, -0.525731112119 ) ; glVertex3d (  0.61803398875,  0.0, -1.61803398875 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d (  1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d (  1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_POLYGON ) ;
+  glNormal3d ( -0.850650808354,  0.0, -0.525731112119 ) ; glVertex3d ( -0.61803398875,  0.0, -1.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
+  glEnd () ;
+
+  glBegin ( GL_POLYGON ) ;
+  glNormal3d (  0.525731112119,  0.850650808354,  0.0 ) ; glVertex3d (  1.61803398875,  0.61803398875,  0.0 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d ( 0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_POLYGON ) ;
+  glNormal3d (  0.525731112119, -0.850650808354,  0.0 ) ; glVertex3d (  1.61803398875, -0.61803398875,  0.0 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d ( 0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_POLYGON ) ;
+  glNormal3d ( -0.525731112119,  0.850650808354,  0.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875,  0.0 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( 0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d ( 0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
+  glEnd () ;
+  glBegin ( GL_POLYGON ) ;
+  glNormal3d ( -0.525731112119, -0.850650808354,  0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875,  0.0 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
+  glEnd () ;
+}
+
+/*
+ *
+ */
+void FGAPIENTRY glutWireOctahedron( void )
+{
+#define RADIUS    1.0f
+  glBegin( GL_LINE_LOOP );
+    glNormal3d( 0.577350269189, 0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
+    glNormal3d( 0.577350269189, 0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
+    glNormal3d( 0.577350269189,-0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
+    glNormal3d( 0.577350269189,-0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
+    glNormal3d(-0.577350269189, 0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
+    glNormal3d(-0.577350269189, 0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
+    glNormal3d(-0.577350269189,-0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
+    glNormal3d(-0.577350269189,-0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
+  glEnd();
+#undef RADIUS
+}
+
+/*
+ *
+ */
+void FGAPIENTRY glutSolidOctahedron( void )
+{
+#define RADIUS    1.0f
+  glBegin( GL_TRIANGLES );
+    glNormal3d( 0.577350269189, 0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
+    glNormal3d( 0.577350269189, 0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
+    glNormal3d( 0.577350269189,-0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
+    glNormal3d( 0.577350269189,-0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
+    glNormal3d(-0.577350269189, 0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
+    glNormal3d(-0.577350269189, 0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
+    glNormal3d(-0.577350269189,-0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
+    glNormal3d(-0.577350269189,-0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
+  glEnd();
+#undef RADIUS
+}
+
+/*
+ *
+ */
+void FGAPIENTRY glutWireTetrahedron( void )
+{
+  /* Magic Numbers:  r0 = ( 1, 0, 0 )
+   *                 r1 = ( -1/3, 2 sqrt(2) / 3, 0 )
+   *                 r2 = ( -1/3, -sqrt(2) / 3, sqrt(6) / 3 )
+   *                 r3 = ( -1/3, -sqrt(2) / 3, -sqrt(6) / 3 )
+   * |r0| = |r1| = |r2| = |r3| = 1
+   * Distance between any two points is 2 sqrt(6) / 3
+   *
+   * Normals:  The unit normals are simply the negative of the coordinates of the point not on the surface.
+   */
+
+  double r0[3] = {             1.0,             0.0,             0.0 } ;
+  double r1[3] = { -0.333333333333,  0.942809041582,             0.0 } ;
+  double r2[3] = { -0.333333333333, -0.471404520791,  0.816496580928 } ;
+  double r3[3] = { -0.333333333333, -0.471404520791, -0.816496580928 } ;
+
+  glBegin( GL_LINE_LOOP ) ;
+    glNormal3d (           -1.0,             0.0,             0.0 ) ; glVertex3dv ( r1 ) ; glVertex3dv ( r3 ) ; glVertex3dv ( r2 ) ;
+    glNormal3d ( 0.333333333333, -0.942809041582,             0.0 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r2 ) ; glVertex3dv ( r3 ) ;
+    glNormal3d ( 0.333333333333,  0.471404520791, -0.816496580928 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r3 ) ; glVertex3dv ( r1 ) ;
+    glNormal3d ( 0.333333333333,  0.471404520791,  0.816496580928 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r1 ) ; glVertex3dv ( r2 ) ;
+  glEnd() ;
+}
+
+/*
+ *
+ */
+void FGAPIENTRY glutSolidTetrahedron( void )
+{
+  /* Magic Numbers:  r0 = ( 1, 0, 0 )
+   *                 r1 = ( -1/3, 2 sqrt(2) / 3, 0 )
+   *                 r2 = ( -1/3, -sqrt(2) / 3, sqrt(6) / 3 )
+   *                 r3 = ( -1/3, -sqrt(2) / 3, -sqrt(6) / 3 )
+   * |r0| = |r1| = |r2| = |r3| = 1
+   * Distance between any two points is 2 sqrt(6) / 3
+   *
+   * Normals:  The unit normals are simply the negative of the coordinates of the point not on the surface.
+   */
+
+  double r0[3] = {             1.0,             0.0,             0.0 } ;
+  double r1[3] = { -0.333333333333,  0.942809041582,             0.0 } ;
+  double r2[3] = { -0.333333333333, -0.471404520791,  0.816496580928 } ;
+  double r3[3] = { -0.333333333333, -0.471404520791, -0.816496580928 } ;
+
+  glBegin( GL_TRIANGLES ) ;
+    glNormal3d (           -1.0,             0.0,             0.0 ) ; glVertex3dv ( r1 ) ; glVertex3dv ( r3 ) ; glVertex3dv ( r2 ) ;
+    glNormal3d ( 0.333333333333, -0.942809041582,             0.0 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r2 ) ; glVertex3dv ( r3 ) ;
+    glNormal3d ( 0.333333333333,  0.471404520791, -0.816496580928 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r3 ) ; glVertex3dv ( r1 ) ;
+    glNormal3d ( 0.333333333333,  0.471404520791,  0.816496580928 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r1 ) ; glVertex3dv ( r2 ) ;
+  glEnd() ;
+}
+
+/*
+ *
+ */
+double icos_r[12][3] = { { 1.0, 0.0, 0.0 },
+  {  0.447213595500,  0.894427191000, 0.0 }, {  0.447213595500,  0.276393202252, 0.850650808354 }, {  0.447213595500, -0.723606797748, 0.525731112119 }, {  0.447213595500, -0.723606797748, -0.525731112119 }, {  0.447213595500,  0.276393202252, -0.850650808354 },
+  { -0.447213595500, -0.894427191000, 0.0 }, { -0.447213595500, -0.276393202252, 0.850650808354 }, { -0.447213595500,  0.723606797748, 0.525731112119 }, { -0.447213595500,  0.723606797748, -0.525731112119 }, { -0.447213595500, -0.276393202252, -0.850650808354 },
+  { -1.0, 0.0, 0.0 } } ;
+int icos_v [20][3] = { { 0, 1, 2 }, { 0, 2, 3 }, { 0, 3, 4 }, { 0, 4, 5 }, { 0, 5, 1 },
+                       { 1, 8, 2 }, { 2, 7, 3 }, { 3, 6, 4 }, { 4, 10, 5 }, { 5, 9, 1 },
+                       { 1, 9, 8 }, { 2, 8, 7 }, { 3, 7, 6 }, { 4, 6, 10 }, { 5, 10, 9 },
+                       { 11, 9, 10 }, { 11, 8, 9 }, { 11, 7, 8 }, { 11, 6, 7 }, { 11, 10, 6 } } ;
+
+void FGAPIENTRY glutWireIcosahedron( void )
+{
+  int i ;
+  for ( i = 0; i < 20; i++ )
+  {
+    double normal[3] ;
+    normal[0] = ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) - ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) ;
+    normal[1] = ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) - ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) ;
+    normal[2] = ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) - ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) ;
+    glBegin ( GL_LINE_LOOP ) ;
+      glNormal3dv ( normal ) ;
+      glVertex3dv ( icos_r[icos_v[i][0]] ) ;
+      glVertex3dv ( icos_r[icos_v[i][1]] ) ;
+      glVertex3dv ( icos_r[icos_v[i][2]] ) ;
+    glEnd () ;
+  }
+}
+
+/*
+ *
+ */
+void FGAPIENTRY glutSolidIcosahedron( void )
+{
+  int i ;
+
+  glBegin ( GL_TRIANGLES ) ;
+  for ( i = 0; i < 20; i++ )
+  {
+    double normal[3] ;
+    normal[0] = ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) - ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) ;
+    normal[1] = ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) - ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) ;
+    normal[2] = ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) - ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) ;
+      glNormal3dv ( normal ) ;
+      glVertex3dv ( icos_r[icos_v[i][0]] ) ;
+      glVertex3dv ( icos_r[icos_v[i][1]] ) ;
+      glVertex3dv ( icos_r[icos_v[i][2]] ) ;
+  }
+
+  glEnd () ;
+}
+
+/*
+ *
+ */
+double rdod_r[14][3] = { { 0.0, 0.0, 1.0 },
+  {  0.707106781187,  0.000000000000,  0.5 }, {  0.000000000000,  0.707106781187,  0.5 }, { -0.707106781187,  0.000000000000,  0.5 }, {  0.000000000000, -0.707106781187,  0.5 },
+  {  0.707106781187,  0.707106781187,  0.0 }, { -0.707106781187,  0.707106781187,  0.0 }, { -0.707106781187, -0.707106781187,  0.0 }, {  0.707106781187, -0.707106781187,  0.0 },
+  {  0.707106781187,  0.000000000000, -0.5 }, {  0.000000000000,  0.707106781187, -0.5 }, { -0.707106781187,  0.000000000000, -0.5 }, {  0.000000000000, -0.707106781187, -0.5 },
+  {  0.0, 0.0, -1.0 } } ;
+int rdod_v [12][4] = { { 0,  1,  5,  2 }, { 0,  2,  6,  3 }, { 0,  3,  7,  4 }, { 0,  4,  8, 1 },
+                       { 5, 10,  6,  2 }, { 6, 11,  7,  3 }, { 7, 12,  8,  4 }, { 8,  9,  5, 1 },
+                       { 5,  9, 13, 10 }, { 6, 10, 13, 11 }, { 7, 11, 13, 12 }, { 8, 12, 13, 9 } } ;
+double rdod_n[12][3] = {
+  {  0.353553390594,  0.353553390594,  0.5 }, { -0.353553390594,  0.353553390594,  0.5 }, { -0.353553390594, -0.353553390594,  0.5 }, {  0.353553390594, -0.353553390594,  0.5 },
+  {  0.000000000000,  1.000000000000,  0.0 }, { -1.000000000000,  0.000000000000,  0.0 }, {  0.000000000000, -1.000000000000,  0.0 }, {  1.000000000000,  0.000000000000,  0.0 },
+  {  0.353553390594,  0.353553390594, -0.5 }, { -0.353553390594,  0.353553390594, -0.5 }, { -0.353553390594, -0.353553390594, -0.5 }, {  0.353553390594, -0.353553390594, -0.5 }
+  } ;
+
+void FGAPIENTRY glutWireRhombicDodecahedron( void )
+{
+  int i ;
+  for ( i = 0; i < 12; i++ )
+  {
+    glBegin ( GL_LINE_LOOP ) ;
+      glNormal3dv ( rdod_n[i] ) ;
+      glVertex3dv ( rdod_r[rdod_v[i][0]] ) ;
+      glVertex3dv ( rdod_r[rdod_v[i][1]] ) ;
+      glVertex3dv ( rdod_r[rdod_v[i][2]] ) ;
+      glVertex3dv ( rdod_r[rdod_v[i][3]] ) ;
+    glEnd () ;
+  }
+}
+
+/*
+ *
+ */
+void FGAPIENTRY glutSolidRhombicDodecahedron( void )
+{
+  int i ;
+
+  glBegin ( GL_QUADS ) ;
+  for ( i = 0; i < 12; i++ )
+  {
+      glNormal3dv ( rdod_n[i] ) ;
+      glVertex3dv ( rdod_r[rdod_v[i][0]] ) ;
+      glVertex3dv ( rdod_r[rdod_v[i][1]] ) ;
+      glVertex3dv ( rdod_r[rdod_v[i][2]] ) ;
+      glVertex3dv ( rdod_r[rdod_v[i][3]] ) ;
+  }
+
+  glEnd () ;
+}
+
+#define NUM_FACES     4
+
+static GLdouble tetrahedron_v[4][3] =  /* Vertices */
+{
+  { -0.5, -0.288675134595, -0.144337567297 },
+  {  0.5, -0.288675134595, -0.144337567297 },
+  {  0.0,  0.577350269189, -0.144337567297 },
+  {  0.0,  0.0,             0.672159013631 }
+} ;
+
+static GLint tetrahedron_i[4][3] =  /* Vertex indices */
+{
+  { 0, 1, 2 }, { 0, 2, 3 }, { 0, 3, 1 }, { 1, 3, 2 }
+} ;
+
+static GLdouble tetrahedron_n[4][3] =  /* Normals */
+{
+  {  0.0,             0.0,            -1.0 },
+  { -0.816496580928,  0.471404520791,  0.333333333333 },
+  {  0.0,            -0.942809041582,  0.333333333333 },
+  {  0.816496580928,  0.471404520791,  0.333333333333 }
+} ;
+
+void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale )
+{
+  int i, j ;
+
+  if ( num_levels == 0 )
+  {
+
+    for ( i = 0 ; i < NUM_FACES ; i++ )
+    {
+      glBegin ( GL_LINE_LOOP ) ;
+      glNormal3dv ( tetrahedron_n[i] ) ;
+      for ( j = 0; j < 3; j++ )
+      {
+        double x = offset[0] + scale * tetrahedron_v[tetrahedron_i[i][j]][0] ;
+        double y = offset[1] + scale * tetrahedron_v[tetrahedron_i[i][j]][1] ;
+        double z = offset[2] + scale * tetrahedron_v[tetrahedron_i[i][j]][2] ;
+        glVertex3d ( x, y, z ) ;
+      }
+
+      glEnd () ;
+    }
+  }
+  else
+  {
+    GLdouble local_offset[3] ;  /* Use a local variable to avoid buildup of roundoff errors */
+    num_levels -- ;
+    scale /= 2.0 ;
+    local_offset[0] = offset[0] + scale * tetrahedron_v[0][0] ;
+    local_offset[1] = offset[1] + scale * tetrahedron_v[0][1] ;
+    local_offset[2] = offset[2] + scale * tetrahedron_v[0][2] ;
+    glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ;
+    local_offset[0] += scale ;
+    glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ;
+    local_offset[0] -= 0.5            * scale ;
+    local_offset[1] += 0.866025403784 * scale ;
+    glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ;
+    local_offset[1] -= 0.577350269189 * scale ;
+    local_offset[2] += 0.816496580928 * scale ;
+    glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ;
+  }
+}
+
+void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale )
+{
+  int i, j ;
+
+  if ( num_levels == 0 )
+  {
+    glBegin ( GL_TRIANGLES ) ;
+
+    for ( i = 0 ; i < NUM_FACES ; i++ )
+    {
+      glNormal3dv ( tetrahedron_n[i] ) ;
+      for ( j = 0; j < 3; j++ )
+      {
+        double x = offset[0] + scale * tetrahedron_v[tetrahedron_i[i][j]][0] ;
+        double y = offset[1] + scale * tetrahedron_v[tetrahedron_i[i][j]][1] ;
+        double z = offset[2] + scale * tetrahedron_v[tetrahedron_i[i][j]][2] ;
+        glVertex3d ( x, y, z ) ;
+      }
+    }
+
+    glEnd () ;
+  }
+  else
+  {
+    GLdouble local_offset[3] ;  /* Use a local variable to avoid buildup of roundoff errors */
+    num_levels -- ;
+    scale /= 2.0 ;
+    local_offset[0] = offset[0] + scale * tetrahedron_v[0][0] ;
+    local_offset[1] = offset[1] + scale * tetrahedron_v[0][1] ;
+    local_offset[2] = offset[2] + scale * tetrahedron_v[0][2] ;
+    glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ;
+    local_offset[0] += scale ;
+    glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ;
+    local_offset[0] -= 0.5            * scale ;
+    local_offset[1] += 0.866025403784 * scale ;
+    glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ;
+    local_offset[1] -= 0.577350269189 * scale ;
+    local_offset[2] += 0.816496580928 * scale ;
+    glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ;
+  }
+}
+
+#undef NUM_FACES
+
+/*** END OF FILE ***/
diff --git a/src/freeglut_init.c b/src/freeglut_init.c
new file mode 100644 (file)
index 0000000..a1367b8
--- /dev/null
@@ -0,0 +1,1120 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define G_LOG_DOMAIN "freeglut-init"
+
+#include "../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, FALSE },  /* Position */
+                      { 300, 300, TRUE }, /* Size */
+                      GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH,  /* DisplayMode */
+                      FALSE, /* ForceDirectContext */
+                      TRUE,  /* TryDirectContext */
+                      FALSE, /* ForceIconic */
+                      FALSE, /* GLDebugSwitch */
+                      FALSE, /* XSyncSwitch */
+                      TRUE,  /* IgnoreKeyRepeat */
+                      0,     /* FPSInterval */
+                      0,     /* SwapCount */
+                      0,     /* SwapTime */
+#ifdef TARGET_HOST_WIN32
+                      { 0, FALSE }, /* Time */
+#else
+                      { { 0, 0 }, FALSE },
+#endif
+                      { NULL, NULL }, /* Timers */
+                      NULL, /* IdleCallback */
+                      NULL, /* MenuStateCallback */
+                      NULL, /* MenuStatusCallback */
+                      { 640, 480, TRUE }, /* GameModeSize */
+                      16,  /* GameModeDepth */
+                      72,  /* GameModeRefresh */
+                      GLUT_ACTION_EXIT, /* ActionOnWindowClose */
+                      GLUT_EXEC_STATE_INIT /* ExecState */
+};
+
+
+/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
+
+/*
+ * A call to this function should initialize all the display stuff...
+ */
+void fgInitialize( const char* displayName )
+{
+#if TARGET_HOST_UNIX_X11
+    /*
+     * Have the display created
+     */
+    fgDisplay.Display = XOpenDisplay( displayName );
+
+    if( fgDisplay.Display == NULL )
+    {
+        /*
+         * Failed to open a display. That's no good.
+         */
+        fgError( "failed to open display '%s'", XDisplayName( displayName ) );
+    }
+
+    /*
+     * Check for the OpenGL GLX extension availability:
+     */
+    if( !glXQueryExtension( fgDisplay.Display, NULL, NULL ) )
+    {
+        /*
+         * GLX extensions have not been found...
+         */
+        fgError( "OpenGL GLX extension not supported by display '%s'", XDisplayName( displayName ) );
+    }
+
+    /*
+     * Grab the default screen for the display we have just opened
+     */
+    fgDisplay.Screen = DefaultScreen( fgDisplay.Display );
+
+    /*
+     * The same applying to the root window
+     */
+    fgDisplay.RootWindow = RootWindow(
+        fgDisplay.Display,
+        fgDisplay.Screen
+    );
+
+    /*
+     * Grab the logical screen's geometry
+     */
+    fgDisplay.ScreenWidth  = DisplayWidth(
+        fgDisplay.Display,
+        fgDisplay.Screen
+    );
+
+    fgDisplay.ScreenHeight = DisplayHeight(
+        fgDisplay.Display,
+        fgDisplay.Screen
+    );
+
+    /*
+     * Grab the physical screen's geometry
+     */
+    fgDisplay.ScreenWidthMM = DisplayWidthMM(
+        fgDisplay.Display,
+        fgDisplay.Screen
+    );
+
+    fgDisplay.ScreenHeightMM = DisplayHeightMM(
+        fgDisplay.Display,
+        fgDisplay.Screen
+    );
+
+    /*
+     * The display's connection number
+     */
+    fgDisplay.Connection = ConnectionNumber( fgDisplay.Display );
+
+    /*
+     * Create the window deletion atom
+     */
+    fgDisplay.DeleteWindow = XInternAtom(
+        fgDisplay.Display,
+        "WM_DELETE_WINDOW",
+        FALSE
+    );
+
+#elif TARGET_HOST_WIN32
+
+    WNDCLASS wc;
+    ATOM atom;
+
+    /*
+     * What we need to do is to initialize the fgDisplay global structure here...
+     */
+    fgDisplay.Instance = GetModuleHandle( NULL );
+
+    /*
+     * Check if the freeglut window class has been registered before...
+     */
+    atom = GetClassInfo( fgDisplay.Instance, "FREEGLUT", &wc );
+
+    /*
+     * ...nope, it has not, and we have to do it right now:
+     */
+    if( atom == 0 )
+    {
+        /*
+         * Make sure the unitialized fields are reset to zero
+         */
+        ZeroMemory( &wc, sizeof(WNDCLASS) );
+
+        /*
+         * Each of the windows should have its own device context...
+         */
+        wc.style          = CS_OWNDC;
+        wc.lpfnWndProc    = fgWindowProc;
+        wc.cbClsExtra     = 0;
+        wc.cbWndExtra     = 0;
+        wc.hInstance      = fgDisplay.Instance;
+        wc.hIcon          = LoadIcon( fgDisplay.Instance, "GLUT_ICON" );
+        if (!wc.hIcon)
+          wc.hIcon        = LoadIcon( NULL, IDI_WINLOGO );
+
+        wc.hCursor        = LoadCursor( NULL, IDC_ARROW );
+        wc.hbrBackground  = NULL;
+        wc.lpszMenuName   = NULL;
+        wc.lpszClassName  = "FREEGLUT";
+
+        /*
+         * Register the window class
+         */
+        atom = RegisterClass( &wc );
+        assert( atom != 0 );
+    }
+
+    /*
+     * The screen dimensions can be obtained via GetSystemMetrics() calls
+     */
+    fgDisplay.ScreenWidth  = GetSystemMetrics( SM_CXSCREEN );
+    fgDisplay.ScreenHeight = GetSystemMetrics( SM_CYSCREEN );
+
+    {
+        /*
+         * Checking the display's size in millimeters isn't too hard, too:
+         */
+        HWND desktop = GetDesktopWindow();
+        HDC  context = GetDC( desktop );
+
+        /*
+         * Grab the appropriate values now (HORZSIZE and VERTSIZE respectably):
+         */
+        fgDisplay.ScreenWidthMM  = GetDeviceCaps( context, HORZSIZE );
+        fgDisplay.ScreenHeightMM = GetDeviceCaps( context, VERTSIZE );
+
+        /*
+         * Whoops, forgot to release the device context :)
+         */
+        ReleaseDC( desktop, context );
+    }
+
+#endif
+
+    /*
+     * Have the joystick device initialized now
+     */
+    fgJoystickInit( 0 );
+}
+
+/*
+ * Perform the freeglut deinitialization...
+ */
+void fgDeinitialize( void )
+{
+    SFG_Timer *timer;
+
+    /*
+     * Check if initialization has been performed before
+     */
+    if( !fgState.Time.Set )
+    {
+        fgWarning( "fgDeinitialize(): fgState.Timer is null => no valid initialization has been performed" );
+        return;
+    }
+
+    /*
+     * Perform the freeglut structure deinitialization
+     */
+    fgDestroyStructure();
+
+    /*
+     * Delete all the timers and their storage list
+     */
+    while ( (timer = fgState.Timers.First) != NULL )
+    {
+      fgListRemove ( &fgState.Timers, &timer->Node ) ;
+      free ( timer ) ;
+    }
+
+    /*
+     * Deinitialize the joystick device
+     */
+    fgJoystickClose();
+
+    /*
+     * Reset the state structure
+     */
+
+    fgState.Position.X = -1 ;
+    fgState.Position.Y = -1 ;
+    fgState.Position.Use = FALSE ;
+
+    fgState.Size.X = 300 ;
+    fgState.Size.Y = 300 ;
+    fgState.Size.Use = TRUE ;
+
+    /*
+     * The default display mode to be used
+     */
+    fgState.DisplayMode = GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH;
+
+    fgState.ForceDirectContext  = FALSE;
+    fgState.TryDirectContext    = TRUE;
+    fgState.ForceIconic         = FALSE;
+    fgState.GLDebugSwitch       = FALSE;
+    fgState.XSyncSwitch         = FALSE;
+    fgState.ActionOnWindowClose = GLUT_ACTION_EXIT ;
+    fgState.ExecState           = GLUT_EXEC_STATE_INIT ;
+
+    /*
+     * Assume we want to ignore the automatic key repeat
+     */
+    fgState.IgnoreKeyRepeat = TRUE;
+
+    /*
+     * Set the default game mode settings
+     */
+    fgState.GameModeSize.X  = 640;
+    fgState.GameModeSize.Y  = 480;
+    fgState.GameModeDepth   =  16;
+    fgState.GameModeRefresh =  72;
+
+    fgState.Time.Set = FALSE ;
+
+    fgState.Timers.First = fgState.Timers.Last = NULL ;
+    fgState.IdleCallback = NULL ;
+    fgState.MenuStateCallback = (FGCBmenuState)NULL ;
+    fgState.MenuStatusCallback = (FGCBmenuStatus)NULL ;
+
+    /*
+     * FPS display
+     */
+    fgState.SwapCount   = 0;
+    fgState.SwapTime    = 0;
+    fgState.FPSInterval = 0;
+
+
+#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 );
+
+#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;
+    int i, j, argc = *pargc;
+
+    /*
+     * Do not allow multiple initialization of the library
+     */
+    if( fgState.Time.Set )
+    {
+        /*
+         * We can't have multiple initialization performed
+         */
+        fgError( "illegal glutInit() reinitialization attemp" );
+    }
+
+    /*
+     * Have the internal freeglut structure initialized now
+     */
+    fgCreateStructure();
+
+    /*
+     * Remember the function's call time
+     */
+#if TARGET_HOST_UNIX_X11
+    gettimeofday(&fgState.Time.Value, NULL);
+#elif TARGET_HOST_WIN32
+    fgState.Time.Value = timeGetTime();
+#endif
+    fgState.Time.Set = TRUE;
+
+    /* check if GLUT_FPS env var is set */
+    {
+        const char *fps = getenv("GLUT_FPS");
+        if (fps) {
+            sscanf(fps, "%d", &fgState.FPSInterval);
+            if (fgState.FPSInterval <= 0)
+                fgState.FPSInterval = 5000;  /* 5000 milliseconds */
+        }
+    }
+
+    /*
+     * Grab the environment variable indicating the X display to use.
+     * This is harmless under Win32, so let's let it stay here...
+     */
+#if TARGET_HOST_WIN32
+    if ( !getenv ( "DISPLAY" ) )
+      displayName = strdup ( "" ) ;
+    else
+#endif
+    displayName = strdup( getenv( "DISPLAY" ) );
+
+    /*
+     * Have the program arguments parsed.
+     */
+    for( i=1; i<argc; i++ )
+    {
+        /*
+         * The X display name settings
+         */
+        if( strcmp( argv[ i ], "-display" ) == 0 )
+        {
+            /*
+             * Check for possible lack of the next argument
+             */
+            if( ++i >= argc )
+                fgError( "-display parameter must be followed by display name" );
+
+            /*
+             * Release the previous display name (the one from app's environment)
+             */
+            free( displayName );
+
+            /*
+             * Make a working copy of the name for us to use
+             */
+            displayName = strdup( argv[ i ] );
+
+            /*
+             * Have both arguments removed
+             */
+            argv[ i - 1 ] = NULL;
+            argv[   i   ] = NULL;
+            (* pargc) -= 2;
+        }
+
+        /*
+         * The geometry settings
+         */
+        else if( strcmp( argv[ i ], "-geometry" ) == 0 )
+        {
+          int result, x, y;
+          unsigned int w, h;
+
+          /*
+           * Again, check if there is at least one more argument
+           */
+          if ( ++i >= argc )
+            fgError( "-geometry parameter must be followed by window geometry settings" );
+
+          /*
+           * Otherwise scan the geometry settings...
+           */
+          result = sscanf ( argv[i], "%dx%d+%d+%d", &x, &y, &w, &h );
+
+          /*
+           * Check what we have been supplied with...
+           */
+          if ( result > 3 )
+            fgState.Size.Y = h ;
+
+          if ( result > 2 )
+            fgState.Size.X = w ;
+
+          if( result > 1 )
+          {
+            if( y < 0 )
+              fgState.Position.Y = fgDisplay.ScreenHeight + y - fgState.Size.Y;
+            else
+              fgState.Position.Y = y;
+          }
+
+          if( result > 0 )
+          {
+            if( x < 0 )
+              fgState.Position.X = fgDisplay.ScreenWidth + x - fgState.Size.X;
+            else
+              fgState.Position.X = x;
+          }
+
+          /*
+           * Have both arguments removed
+           */
+          argv[ i - 1 ] = NULL;
+          argv[   i   ] = NULL;
+          (* pargc) -= 2;
+        }
+
+        /*
+         * The direct/indirect OpenGL contexts settings
+         */
+        else if( strcmp( argv[ i ], "-direct" ) == 0)
+        {
+            /*
+             * We try to force direct rendering...
+             */
+            if( fgState.TryDirectContext == FALSE )
+                fgError( "parameters ambiguity, -direct and -indirect cannot be both specified" );
+
+            fgState.ForceDirectContext = TRUE;
+            argv[ i ] = NULL;
+            (* pargc)--;
+        }
+        else if( strcmp( argv[ i ], "-indirect" ) == 0 )
+        {
+            /*
+             * We try to force indirect rendering...
+             */
+            if( fgState.ForceDirectContext == TRUE )
+                fgError( "parameters ambiguity, -direct and -indirect cannot be both specified" );
+
+            fgState.TryDirectContext = FALSE;
+            argv[ i ] = NULL;
+            (* pargc)--;
+        }
+
+        /*
+         * The '-iconic' parameter makes all new top-level
+         * windows created in iconified state...
+         */
+        else if( strcmp( argv[ i ], "-iconic" ) == 0 )
+        {
+            fgState.ForceIconic = TRUE;
+            argv[ i ] = NULL;
+            (* pargc)--;
+        }
+
+        /*
+         * The '-gldebug' option activates some OpenGL state debugging features
+         */
+        else if( strcmp( argv[ i ], "-gldebug" ) == 0 )
+        {
+            fgState.GLDebugSwitch = TRUE;
+            argv[ i ] = NULL;
+            (* pargc)--;
+        }
+
+        /*
+         * The '-sync' option activates X protocol synchronization (for debugging purposes)
+         */
+        else if( strcmp( argv[ i ], "-sync" ) == 0 )
+        {
+            fgState.XSyncSwitch = TRUE;
+            argv[ i ] = NULL;
+            (* pargc)--;
+        }
+    }
+
+    /*
+     * Have the arguments list compacted now
+     */
+    j = 2 ;
+    for( i = 1; i < *pargc; i++, j++ )
+    {
+      if( argv[ i ] == NULL )
+      {
+        while ( argv[j] == NULL ) j++ ;  /* Guaranteed to end because there are "*pargc" arguments left */
+        argv[i] = argv[j] ;
+      }
+    }
+
+    /*
+     * Have the display created now. As I am too lazy to implement
+     * the program arguments parsing, we will have the DISPLAY
+     * environment variable used for opening the X display:
+     */
+    fgInitialize( displayName );
+
+    /*
+     * Check for the minus one settings for both position and size...
+     */
+    if( fgState.Position.X < 0 || fgState.Position.Y < 0 )
+        fgState.Position.Use = FALSE;
+
+    if( fgState.Size.X < 0 || fgState.Size.Y < 0 )
+        fgState.Size.Use = FALSE;
+
+    /*
+     * Do not forget about releasing the display name string
+     */
+    free( displayName );
+}
+
+/*
+ * Sets the default initial window position for new windows
+ */
+void FGAPIENTRY glutInitWindowPosition( int x, int y )
+{
+    /*
+     * The settings can be disables when both coordinates are negative
+     */
+    if( (x >= 0) && (y >= 0) )
+    {
+        /*
+         * We want to specify the initial position of each of the windows
+         */
+        fgState.Position.X   =    x;
+        fgState.Position.Y   =    y;
+        fgState.Position.Use = TRUE;
+    }
+    else
+    {
+        /*
+         * The initial position of each of the windows is specified by the wm
+         */
+        fgState.Position.X   =    -1;
+        fgState.Position.Y   =    -1;
+        fgState.Position.Use = FALSE;
+    }
+}
+
+/*
+ * Sets the default initial window size for new windows
+ */
+void FGAPIENTRY glutInitWindowSize( int width, int height )
+{
+    /*
+     * The settings can be disables when both values are negative
+     */
+    if( (width > 0) && (height > 0) )
+    {
+        /*
+         * We want to specify the initial size of each of the windows
+         */
+        fgState.Size.X   =  width;
+        fgState.Size.Y   = height;
+        fgState.Size.Use =   TRUE;
+    }
+    else
+    {
+        /*
+         * The initial size of each of the windows is specified by the wm (officially this is an error condition)
+         */
+        fgState.Size.X   =    -1;
+        fgState.Size.Y   =    -1;
+        fgState.Size.Use = 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 ------------------------------------------ */
+
+#if 0 /* FIXME: CJP */
+/*
+ * There is a discrete number of comparison operators we can encounter:
+ *
+ *     comparison ::= "=" | "!=" | "<" | ">" | "<=" | ">=" | "~"
+ */
+#define  FG_NONE           0x0000
+#define  FG_EQUAL          0x0001
+#define  FG_NOT_EQUAL      0x0002
+#define  FG_LESS           0x0003
+#define  FG_MORE           0x0004
+#define  FG_LESS_OR_EQUAL  0x0005
+#define  FG_MORE_OR_EQUAL  0x0006
+#define  FG_CLOSEST        0x0007
+
+/*
+ * The caller can feed us with a number of capability tokens:
+ *
+ * capability ::= "alpha" | "acca" | "acc" | "blue" | "buffer" | "conformant" | "depth" | "double" |
+ *                "green" | "index" | "num" | "red" | "rgba" | "rgb" | "luminance" | "stencil" |
+ *                "single" | "stereo" | "samples" | "slow" | "win32pdf" | "xvisual" | "xstaticgray" |
+ *                "xgrayscale" | "xstaticcolor" | "xpseudocolor" | "xtruecolor" | "xdirectcolor"
+ */
+static gchar* g_Tokens[] =
+{
+    "none", "alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double", "green",
+    "index", "num", "red", "rgba", "rgb", "luminance", "stencil", "single", "stereo", "samples",
+    "slow", "win32pdf", "xvisual", "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor",
+    "xtruecolor", "xdirectcolor", NULL
+};
+
+/*
+ * The structure to hold the parsed display string tokens
+ */
+typedef struct tagSFG_Capability SFG_Capability;
+struct tagSFG_Capability
+{
+    gint capability;        /* the capability token enumerator */
+    gint comparison;        /* the comparison operator used    */
+    gint value;             /* the value we're comparing to    */
+};
+
+/*
+ * The scanner configuration for the init display string
+ */
+static GScannerConfig fgInitDisplayStringScannerConfig =
+{
+    ( " \t\r\n" )               /* cset_skip_characters     */,
+    (
+        G_CSET_a_2_z
+        "_"
+        G_CSET_A_2_Z
+    )                                  /* cset_identifier_first    */,
+    (
+        G_CSET_a_2_z
+        "_0123456789"
+        G_CSET_A_2_Z
+        G_CSET_LATINS
+        G_CSET_LATINC
+        "<>!=~"
+    )                                  /* cset_identifier_nth      */,
+    ( "#\n" )                      /* cpair_comment_single     */,
+    FALSE                                  /* case_sensitive           */,
+    TRUE                                   /* skip_comment_multi       */,
+    TRUE                                   /* skip_comment_single      */,
+    TRUE                                   /* scan_comment_multi       */,
+    TRUE                                   /* scan_identifier          */,
+    FALSE                                  /* scan_identifier_1char    */,
+    FALSE                                  /* scan_identifier_NULL     */,
+    TRUE                                   /* scan_symbols             */,
+    FALSE                                  /* scan_binary              */,
+    TRUE                                   /* scan_octal               */,
+    TRUE                                   /* scan_float               */,
+    TRUE                                   /* scan_hex                 */,
+    FALSE                                  /* scan_hex_dollar          */,
+    TRUE                                   /* scan_string_sq           */,
+    TRUE                                   /* scan_string_dq           */,
+    TRUE                                   /* numbers_2_int            */,
+    FALSE                                  /* int_2_float              */,
+    FALSE                                  /* identifier_2_string      */,
+    TRUE                                   /* char_2_token             */,
+    FALSE                                  /* symbol_2_token           */,
+    FALSE                                  /* scope_0_fallback         */,
+};
+
+/*
+ * Sets the default display mode for all new windows using a string
+ */
+void FGAPIENTRY glutInitDisplayString( char* displayMode )
+{
+    /*
+     * display_string ::= (switch)
+     * switch         ::= capability [comparison value]
+     * comparison     ::= "=" | "!=" | "<" | ">" | "<=" | ">=" | "~"
+     * capability     ::= "alpha" | "acca" | "acc" | "blue" | "buffer" | "conformant" |
+     *                    "depth" | "double" | "green" | "index" | "num" | "red" | "rgba" |
+     *                    "rgb" | "luminance" | "stencil" | "single" | "stereo" |
+     *                    "samples" | "slow" | "win32pdf" | "xvisual" | "xstaticgray" |
+     *                    "xgrayscale" | "xstaticcolor" | "xpseudocolor" |
+     *                    "xtruecolor" | "xdirectcolor"
+     * value          ::= 0..9 [value]
+     *
+     * The display string grammar. This should be EBNF, but I couldn't find the definitions so, to
+     * clarify: (expr) means 0 or more times the expression, [expr] means 0 or 1 times expr.
+     *
+     * Create a new GLib lexical analyzer to process the display mode string
+     */
+    GScanner* scanner = g_scanner_new( &fgInitDisplayStringScannerConfig );
+    GList* caps = NULL;
+    gint i;
+
+    /*
+     * Fail if the display mode string is empty or the scanner failed to initialize
+     */
+    freeglut_return_if_fail( (scanner != NULL) && (strlen( displayMode ) > 0) );
+
+    /*
+     * Set the scanner's input name (for debugging)
+     */
+    scanner->input_name = "glutInitDisplayString";
+
+    /*
+     * Start the lexical analysis of the extensions string
+     */
+    g_scanner_input_text( scanner, displayMode, strlen( displayMode ) );
+
+    /*
+     * While there are any more tokens to be checked...
+     */
+    while( !g_scanner_eof( scanner ) )
+    {
+        /*
+         * Actually we're expecting only string tokens
+         */
+        GTokenType tokenType = g_scanner_get_next_token( scanner );
+
+        /*
+         * We are looking for identifiers
+         */
+        if( tokenType == G_TOKEN_IDENTIFIER )
+        {
+            gchar* capability  = NULL;  /* the capability identifier string (always present) */
+            gint   capID       =    0;  /* the capability identifier value (from g_Tokens)   */
+            gint   comparison  =    0;  /* the comparison operator value, see definitions    */
+            gchar* valueString = NULL;  /* if the previous one is present, this is needed    */
+            gint   value       =    0;  /* the integer value converted using a strtol call   */
+            SFG_Capability* capStruct;  /* the capability description structure              */
+
+            /*
+             * OK. The general rule of thumb that we always should be getting a capability identifier
+             * string (see the grammar description). If it is followed by a comparison identifier, then
+             * there must follow an integer value we're comparing the capability to...
+             *
+             * Have the current token analyzed with that in mind...
+             */
+            for( i=0; i<(gint) strlen( scanner->value.v_identifier ); i++ )
+            {
+                gchar c = scanner->value.v_identifier[ i ];
+
+                if( (c == '=') || (c == '!') || (c == '<') || (c == '>') || (c == '~') )
+                    break;
+            }
+
+            /*
+             * Here we go with the length of the capability identifier string.
+             * In the worst of cases, it is as long as the token identifier.
+             */
+            capability = g_strndup( scanner->value.v_identifier, i );
+
+            /*
+             * OK. Is there a chance for comparison and value identifiers to follow?
+             * Note: checking against i+1 as this handles two cases: single character
+             * comparison operator and first of value's digits, which must always be
+             * there, or the two-character comparison operators.
+             */
+            if( (i + 1) < (gint) strlen( scanner->value.v_identifier ) )
+            {
+                /*
+                 * Yeah, indeed, it is the i-th character to start the identifier, then.
+                 */
+                gchar c1 = scanner->value.v_identifier[ i + 0 ];
+                gchar c2 = scanner->value.v_identifier[ i + 1 ];
+
+                if( (c1 == '=')                ) { i += 1; comparison = FG_EQUAL;         } else
+                if( (c1 == '!') && (c2 == '=') ) { i += 2; comparison = FG_NOT_EQUAL;     } else
+                if( (c1 == '<') && (c2 == '=') ) { i += 2; comparison = FG_LESS_OR_EQUAL; } else
+                if( (c1 == '>') && (c2 == '=') ) { i += 2; comparison = FG_MORE_OR_EQUAL; } else
+                if( (c1 == '<')                ) { i += 1; comparison = FG_LESS;          } else
+                if( (c1 == '>')                ) { i += 1; comparison = FG_MORE;          } else
+                if( (c1 == '~')                ) { i += 1; comparison = FG_CLOSEST;       } else
+                g_warning( "invalid comparison operator in token `%s'", scanner->value.v_identifier );
+            }
+
+            /*
+             * Grab the value string that must follow the comparison operator...
+             */
+            if( comparison != FG_NONE && i < (gint) strlen( scanner->value.v_identifier ) )
+                valueString = strdup( scanner->value.v_identifier + i );
+
+            /*
+             * If there was a value string, convert it to integer...
+             */
+            if( comparison != FG_NONE && strlen( valueString ) > 0 )
+                value = strtol( valueString, NULL, 0 );
+
+            /*
+             * Now we need to match the capability string and its ID
+             */
+            for( i=0; g_Tokens[ i ]!=NULL; i++ )
+            {
+                if( strcmp( capability, g_Tokens[ i ] ) == 0 )
+                {
+                    /*
+                     * Looks like we've found the one we were looking for
+                     */
+                    capID = i;
+                    break;
+                }
+            }
+
+            /*
+             * Create a new capability description structure
+             */
+            capStruct = g_new0( SFG_Capability, 1 );
+
+            /*
+             * Fill in the cap's values, as we have parsed it:
+             */
+            capStruct->capability =      capID;
+            capStruct->comparison = comparison;
+            capStruct->value      =      value;
+
+            /*
+             * Add the new capabaility to the caps list
+             */
+            caps = g_list_append( caps, capStruct );
+
+            /*
+             * Clean up the local mess and keep rolling on
+             */
+            g_free( valueString );
+            g_free( capability );
+        }
+    }
+
+    /*
+     * Now that we have converted the string into somewhat more machine-friendly
+     * form, proceed with matching the frame buffer configuration...
+     *
+     * The caps list could be passed to a function that would try finding the closest 
+     * matching pixel format, visual, frame buffer configuration or whatever. It would 
+     * be good to convert the glutInitDisplayMode() to use the same method.
+     */
+#if 0
+    g_message( "found %i capability preferences", g_list_length( caps ) );
+
+    g_message( "token `%s': cap: %i, com: %i, val: %i",
+        scanner->value.v_identifier,
+        capStruct->capability,
+        capStruct->comparison,
+        capStruct->value
+    );
+#endif
+
+    /*
+     * Free the capabilities we have parsed
+     */
+    for( i=0; i<(gint) g_list_length( caps ); i++ )
+        g_free( g_list_nth( caps, i )->data );
+
+    /*
+     * Destroy the capabilities list itself
+     */
+    g_list_free( caps );
+
+    /*
+     * Free the lexical scanner now...
+     */
+    g_scanner_destroy( scanner );
+}
+#endif
+
+#define NUM_TOKENS             28
+static char* Tokens[] =
+{
+    "alpha", "acca", "acc", "blue", "buffer", "conformant", "depth", "double", "green",
+    "index", "num", "red", "rgba", "rgb", "luminance", "stencil", "single", "stereo", "samples",
+    "slow", "win32pdf", "xvisual", "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor",
+    "xtruecolor", "xdirectcolor"
+};
+
+static int TokenLengths[] =
+{
+         5,      4,     3,      4,        6,           10,       5,        6,       5,
+         5,     3,     3,      4,     3,           9,         7,        6,        6,         7,
+        4,          8,         7,            11,           10,             12,             12,
+             10,             12
+};
+
+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 = 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 ( strncmp ( token, Tokens[i], TokenLengths[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":  matches the Win32 Pixel Format Descriptor by number */
+#ifdef TARGET_HOST_WIN32
+#endif
+      break ;
+
+    case 21 :  /* "xvisual":  matches the X visual ID by number */
+#ifdef TARGET_HOST_UNIX_X11
+#endif
+      break ;
+
+    case 22 :  /* "xstaticgray":  boolean indicating if the frame buffer configuration's X visual is of type StaticGray */
+#ifdef TARGET_HOST_UNIX_X11
+#endif
+      break ;
+
+    case 23 :  /* "xgrayscale":  boolean indicating if the frame buffer configuration's X visual is of type GrayScale */
+#ifdef TARGET_HOST_UNIX_X11
+#endif
+      break ;
+
+    case 24 :  /* "xstaticcolor":  boolean indicating if the frame buffer configuration's X visual is of type StaticColor */
+#ifdef TARGET_HOST_UNIX_X11
+#endif
+      break ;
+
+    case 25 :  /* "xpseudocolor":  boolean indicating if the frame buffer configuration's X visual is of type PseudoColor */
+#ifdef TARGET_HOST_UNIX_X11
+#endif
+      break ;
+
+    case 26 :  /* "xtruecolor":  boolean indicating if the frame buffer configuration's X visual is of type TrueColor */
+#ifdef TARGET_HOST_UNIX_X11
+#endif
+      break ;
+
+    case 27 :  /* "xdirectcolor":  boolean indicating if the frame buffer configuration's X visual is of type DirectColor */
+#ifdef TARGET_HOST_UNIX_X11
+#endif
+      break ;
+
+    case 28 :  /* Unrecognized */
+      printf ( "WARNING - Display string token not recognized:  %s\n", 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 ***/
diff --git a/src/freeglut_internal.h b/src/freeglut_internal.h
new file mode 100644 (file)
index 0000000..5b9df43
--- /dev/null
@@ -0,0 +1,705 @@
+/*
+ * 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
+
+/* XXX Update these for each release! */
+#define  VERSION_MAJOR 1
+#define  VERSION_MINOR 4
+#define  VERSION_PATCH 0 
+
+/*
+ * Freeglut is meant to be available under all Unix/X11 and Win32 platforms.
+ */
+#if !defined(_WIN32)
+#   define  TARGET_HOST_UNIX_X11    1
+#   define  TARGET_HOST_WIN32       0
+#else
+#   define  TARGET_HOST_UNIX_X11    0
+#   define  TARGET_HOST_WIN32       1
+#endif
+
+#define  FREEGLUT_MAX_MENUS         3
+#define  FREEGLUT_DEBUG             1
+
+#if FREEGLUT_DEBUG
+    #undef   G_DISABLE_ASSERT
+    #undef   G_DISABLE_CHECKS
+#else
+    #define  G_DISABLE_ASSERT
+    #define  G_DISABLE_CHECKS
+#endif
+
+/*
+ * Somehow all Win32 include headers depend on this one:
+ */
+#if TARGET_HOST_WIN32
+#include <windows.h>
+#include <windowsx.h>
+
+#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>
+#include <assert.h>
+#include <stdarg.h>
+#if TARGET_HOST_UNIX_X11
+#include <sys/time.h>
+#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>
+
+    #ifndef __sgi
+    #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 (* FGCBmotion        )( int, int );
+typedef void (* FGCBpassive       )( int, int );
+typedef void (* FGCBentry         )( int );
+typedef void (* FGCBwindowStatus  )( int );
+typedef void (* FGCBselect        )( int, int, int );
+typedef void (* FGCBjoystick      )( unsigned int, int, int, int );
+typedef void (* FGCBkeyboardUp    )( unsigned char, int, int );
+typedef void (* FGCBspecialUp     )( int, int, int );
+typedef void (* FGCBoverlayDisplay)( void );
+typedef void (* FGCBspaceMotion   )( int, int, int );
+typedef void (* FGCBspaceRotate   )( int, int, int );
+typedef void (* FGCBspaceButton   )( int, int );
+typedef void (* FGCBdials         )( int, int );
+typedef void (* FGCBbuttonBox     )( int, int );
+typedef void (* FGCBtabletMotion  )( int, int );
+typedef void (* FGCBtabletButton  )( int, int, int, int );
+typedef void (* FGCBdestroy       )( void );
+
+/*
+ * 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
+{
+#ifdef WIN32
+    DWORD Value;
+#else
+    struct timeval  Value;
+#endif
+    GLboolean       Set;
+};
+
+/*
+ * An enumeration containing the state of the GLUT execution:  initializing, running, or stopping
+ */
+typedef enum {
+  GLUT_EXEC_STATE_INIT,
+  GLUT_EXEC_STATE_RUNNING,
+  GLUT_EXEC_STATE_STOP
+} fgExecutionState ;
+
+/*
+ * This structure holds different freeglut settings
+ */
+typedef struct tagSFG_State SFG_State;
+struct tagSFG_State
+{
+    SFG_XYUse        Position;             /* The default windows' position     */
+    SFG_XYUse        Size;                 /* The default windows' size         */
+    unsigned int     DisplayMode;          /* The display mode for new windows  */
+
+    GLboolean        ForceDirectContext;   /* Should we force direct contexts?  */
+    GLboolean        TryDirectContext;     /* What about giving a try to?       */
+
+    GLboolean        ForceIconic;          /* All new top windows are iconified */
+
+    GLboolean        GLDebugSwitch;        /* OpenGL state debugging switch     */
+    GLboolean        XSyncSwitch;          /* X11 sync protocol switch          */
+
+    GLboolean        IgnoreKeyRepeat;      /* Whether to ignore key repeat...   */
+
+    GLuint           FPSInterval;          /* Interval between FPS printfs      */
+    GLuint           SwapCount;            /* Count of glutSwapBuffer calls     */
+    GLuint           SwapTime;             /* Time of last SwapBuffers          */
+
+    SFG_Time         Time;                 /* The time that glutInit was called */
+    SFG_List         Timers;               /* The freeglut timer hooks          */
+
+    FGCBidle         IdleCallback;         /* The global idle callback          */
+
+    FGCBmenuState    MenuStateCallback;    /* Menu callbacks are global         */
+    FGCBmenuStatus   MenuStatusCallback;
+
+    SFG_XYUse        GameModeSize;         /* The game mode screen's dimensions */
+    int              GameModeDepth;        /* The pixel depth for game mode     */
+    int              GameModeRefresh;      /* The refresh rate for game mode    */
+
+    int              ActionOnWindowClose ; /* Action when user clicks "x" on window header bar */
+
+    fgExecutionState ExecState ;           /* Current state of the GLUT execution */
+};
+
+/*
+ * 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
+    XF86VidModeModeLine DisplayMode;    /* Current screen's display settings */
+    int             DisplayModeClock;   /* The display mode's refresh rate   */
+#endif
+
+#elif TARGET_HOST_WIN32
+    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            */
+};
+
+/*
+ * A window and its OpenGL context. The contents of this structure
+ * are highly dependant on the target operating system we aim at...
+ */
+typedef struct tagSFG_Context SFG_Context;
+struct tagSFG_Context
+{
+#if TARGET_HOST_UNIX_X11
+    Window          Handle;             /* The window's handle                 */
+    GLXContext      Context;            /* The OpenGL context                  */
+    XVisualInfo*    VisualInfo;         /* The window's visual information     */
+
+#elif TARGET_HOST_WIN32
+    HWND            Handle;             /* The window's handle                 */
+    HDC             Device;             /* The window's device context         */
+    HGLRC           Context;            /* The window's WGL context            */
+
+#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         */
+
+    GLboolean       Redisplay;          /* Do we have to redisplay?          */
+    GLboolean       Visible;            /* Is the window visible now         */
+
+    int             Cursor;             /* The currently selected cursor     */
+    int             Modifiers;          /* The current ALT/SHIFT/CTRL state  */
+
+    long            JoystickPollRate;   /* The joystick polling rate         */
+    long            JoystickLastPoll;   /* When the last poll has happened   */
+
+    int             MouseX, MouseY;     /* The most recent mouse position    */
+
+    GLboolean       IsGameMode;         /* Is this the game mode window?     */
+
+#if TARGET_HOST_WIN32
+    GLboolean       NeedToResize;       /* Do we need to explicitly resize?  */
+#endif
+};
+
+/*
+ * The window callbacks the user can supply us with. Should be kept portable.
+ */
+typedef struct tagSFG_WindowCallbacks SFG_WindowCallbacks;
+struct tagSFG_WindowCallbacks
+{
+    /*
+     * Following callbacks are fully supported right now
+     * and are ready to be tested for GLUT conformance:
+     */
+    FGCBdisplay         Display;
+    FGCBreshape         Reshape;
+    FGCBkeyboard        Keyboard;
+    FGCBkeyboardUp      KeyboardUp;
+    FGCBspecial         Special;
+    FGCBspecialUp       SpecialUp;
+    FGCBmouse           Mouse;
+    FGCBmotion          Motion;
+    FGCBpassive         Passive;
+    FGCBentry           Entry;
+    FGCBvisibility      Visibility;
+    FGCBwindowStatus    WindowStatus;
+    FGCBjoystick        Joystick;
+    FGCBdestroy         Destroy;
+
+    /*
+     * Those callbacks are being ignored for the moment
+     */
+    FGCBselect          Select;
+    FGCBoverlayDisplay  OverlayDisplay;
+    FGCBspaceMotion     SpaceMotion;
+    FGCBspaceRotate     SpaceRotation;
+    FGCBspaceButton     SpaceButton;
+    FGCBdials           Dials;
+    FGCBbuttonBox       ButtonBox;
+    FGCBtabletMotion    TabletMotion;
+    FGCBtabletButton    TabletButton;
+};
+
+/*
+ * This structure describes a menu
+ */
+typedef struct tagSFG_Menu SFG_Menu;
+struct tagSFG_Menu
+{
+    SFG_Node            Node;
+    void               *UserData ;              /* A. Donev:  User data passed back at callback */
+    int                 ID;                     /* The global menu ID        */
+    SFG_List            Entries;                /* The menu entries list     */
+    FGCBmenu            Callback;               /* The menu callback         */
+    FGCBdestroy         Destroy;                /* A. Donev:  Destruction callback         */
+    GLboolean           IsActive;               /* Is the menu selected?     */
+    int                 Width;                  /* Menu box width in pixels  */
+    int                 Height;                 /* Menu box height in pixels */
+    int                 X, Y;                   /* Menu box raster position  */
+};
+
+/*
+ * This is a menu entry
+ */
+typedef struct tagSFG_MenuEntry SFG_MenuEntry;
+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.
+ */
+typedef struct tagSFG_Window SFG_Window;
+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_WindowCallbacks Callbacks;              /* The window callbacks      */
+    void               *UserData ;              /* A. Donev:  A pointer to user data used in rendering */
+
+    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  */
+};
+
+/*
+ * A linked list structure of windows
+ */
+typedef struct tagSFG_WindowList SFG_WindowList ;
+struct tagSFG_WindowList
+{
+  SFG_Window *window ;
+  GLboolean needToClose ;
+  SFG_WindowList *next ;
+} ;
+
+/*
+ * 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_Window*         Window;                 /* The currently active win. */
+    SFG_Menu*           Menu;                   /* Same, but menu...         */
+
+    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 ;              /* The origin of the character relative to the draw location */
+};
+
+/*
+ * 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_assert_ready                      assert( fgState.Time.Set );
+
+/*
+ * 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 and menu set, respectively:
+ */
+#define  freeglut_assert_window                     assert( fgStructure.Window != NULL );
+#define  freeglut_assert_menu                       assert( fgStructure.Menu != NULL );
+
+/*
+ * The initialize and deinitialize functions get called on glutInit()
+ * and glutMainLoop() end respectively. They should create/clean up
+ * everything inside of the freeglut
+ */
+void fgInitialize( const char* displayName );
+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 check 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
+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.
+ * Defined in freeglut_structure.c, freeglut_window.c.
+ */
+SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title, int x, int y, int w, int h, GLboolean gameMode );
+void        fgSetWindow ( SFG_Window *window ) ;
+void        fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode, int isSubWindow );
+void        fgCloseWindow( SFG_Window* window );
+void        fgAddToWindowDestroyList ( SFG_Window* window, GLboolean needToClose ) ;
+void        fgCloseWindows () ;
+void        fgDestroyWindow( SFG_Window* window, GLboolean needToClose );
+
+/*
+ * Menu creation and destruction. Defined in freeglut_structure.c
+ */
+SFG_Menu*   fgCreateMenu( FGCBmenu menuCallback );
+void        fgDestroyMenu( SFG_Menu* menu );
+
+/*
+ * Joystick device management functions, defined in freeglut_joystick.c
+ */
+void        fgJoystickInit( int ident );
+void        fgJoystickClose( void );
+void        fgJoystickPollWindow( SFG_Window* window );
+
+/*
+ * 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.
+ */
+#if TARGET_HOST_UNIX_X11
+    SFG_Window* fgWindowByHandle( Window hWindow );
+#elif TARGET_HOST_WIN32
+
+    SFG_Window* fgWindowByHandle( HWND hWindow );
+#endif
+
+/*
+ * 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 that 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 fgActivateMenu( SFG_Window* window, int button );
+void fgExecuteMenuCallback( SFG_Menu* menu ) ;
+GLboolean fgCheckActiveMenu ( SFG_Window *window, SFG_Menu *menu ) ;
+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 );
+
+/*
+ * Display the mouse cursor using OpenGL calls. The function
+ * is defined in freeglut_cursor.c file.
+ */
+void fgDisplayCursor( void );
+
+/*
+ * Elapsed time as per glutGet(GLUT_ELAPSED_TIME).
+ */
+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);
+
+/*
+ * Error Messages functions
+ */
+void fgError( const char *fmt, ... );
+void fgWarning( const char *fmt, ... );
+
+#endif /* FREEGLUT_INTERNAL_H */
+
+/*** END OF FILE ***/
diff --git a/src/freeglut_joystick.c b/src/freeglut_joystick.c
new file mode 100644 (file)
index 0000000..a47d491
--- /dev/null
@@ -0,0 +1,605 @@
+/*
+ * freeglut_joystick.c
+ *
+ * Joystick handling code
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Steve Baker, <sjbaker1@airmail.net>
+ *
+ * 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.
+ */
+
+/*
+ * PWO: this is not exactly what Steve Baker has done for PLIB, as I had to convert
+ *      it from C++ to C. And I've also reformatted it a bit (that's my little
+ *      personal deviation :]) I don't really know if it is still portable...
+ *      Steve: could you please add some comments to the code? :)
+ *
+ * FreeBSD port - courtesy of Stephen Montgomery-Smith <stephen@math.missouri.edu>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define G_LOG_DOMAIN "freeglut-joystick"
+
+#include "../include/GL/freeglut.h"
+#include "freeglut_internal.h"
+
+/*
+ * PWO: I don't like it at all. It's a mess. Could it be cleared?
+ */
+#ifdef WIN32
+#   include <windows.h>
+#   if defined( __CYGWIN32__ ) || defined( __CYGWIN__ )
+#       define NEAR /* */
+#       define FAR  /* */
+#   endif
+#   include <mmsystem.h>
+#   include <string.h>
+#else
+#   include <unistd.h>
+#   include <fcntl.h>
+#   ifdef __FreeBSD__
+#       include <machine/joystick.h>
+#       define JS_DATA_TYPE joystick
+#       define JS_RETURN (sizeof(struct JS_DATA_TYPE))
+#   elif defined(__linux__)
+#       include <sys/ioctl.h>
+#       include <linux/joystick.h>
+#       include <errno.h>
+
+        /*
+         * Check the joystick driver version
+         */
+#       ifdef JS_VERSION
+#           if JS_VERSION >= 0x010000
+#               define JS_NEW
+#           endif
+#       endif
+#   else
+#       ifndef JS_DATA_TYPE
+
+            /*
+             * Not Windoze and no joystick driver...
+             *
+             * Well - we'll put these values in and that should
+             * allow the code to at least compile. The JS open
+             * routine should error out and shut off all the code
+             * downstream anyway
+             */
+            struct JS_DATA_TYPE
+            {
+                int buttons;
+                int x;
+                int y;
+            };
+
+#           define JS_RETURN (sizeof(struct JS_DATA_TYPE))
+#       endif
+#   endif
+#endif
+
+#ifdef WIN32
+#   define _JS_MAX_AXES 6
+#else
+#   ifdef __FreeBSD__
+#       define _JS_MAX_AXES 2
+#   else
+#       define _JS_MAX_AXES 6
+#   endif
+#endif
+
+typedef struct tagSFG_Joystick SFG_Joystick;
+struct tagSFG_Joystick
+{
+#ifdef __FreeBSD__
+    int         id;
+#endif
+
+#ifdef WIN32
+    JOYINFOEX   js;
+    UINT        js_id;
+#else
+#   ifdef JS_NEW
+        struct js_event js;
+        int         tmp_buttons;
+        float       tmp_axes[ _JS_MAX_AXES ];
+#   else
+        struct JS_DATA_TYPE js;
+#   endif
+
+    char fname[ 128 ];
+    int  fd;
+#endif
+
+    GLboolean error;
+    int       num_axes;
+    int       num_buttons;
+
+    float dead_band[ _JS_MAX_AXES ];
+    float saturate [ _JS_MAX_AXES ];
+    float center   [ _JS_MAX_AXES ];
+    float max      [ _JS_MAX_AXES ];
+    float min      [ _JS_MAX_AXES ];
+};
+
+/*
+ * The static joystick structure pointer
+ */
+static SFG_Joystick* fgJoystick = NULL;
+
+/*
+ * Read the raw joystick data
+ */
+static void fghJoystickRawRead ( SFG_Joystick* joy, int* buttons, float* axes )
+{
+#ifdef WIN32
+    MMRESULT status;
+#else
+    int status;
+#endif
+
+    int i;
+
+    if( joy->error )
+    {
+        if( buttons )
+            *buttons = 0 ;
+
+        if( axes )
+            for( i=0; i<joy->num_axes; i++ )
+                axes[ i ] = 1500.0f;
+
+        return;
+    }
+
+#ifdef WIN32
+    status = joyGetPosEx( joy->js_id, &joy->js );
+
+    if( status != JOYERR_NOERROR )
+    {
+        joy->error = TRUE;
+        return;
+    }
+
+    if( buttons )
+        *buttons = joy->js.dwButtons;
+
+    if( axes )
+    {
+        /*
+         * WARNING - Fall through case clauses!!
+         */
+        switch( joy->num_axes )
+        {
+           case 6: axes[5] = (float) joy->js.dwVpos;
+           case 5: axes[4] = (float) joy->js.dwUpos;
+           case 4: axes[3] = (float) joy->js.dwRpos;
+           case 3: axes[2] = (float) joy->js.dwZpos;
+           case 2: axes[1] = (float) joy->js.dwYpos;
+           case 1: axes[0] = (float) joy->js.dwXpos;
+        }
+    }
+#else
+#   ifdef JS_NEW
+
+    while( 1 )
+    {
+        status = read( joy->fd, &joy->js, sizeof(struct js_event) );
+
+        if( status != sizeof(struct js_event) )
+        {
+               if( errno == EAGAIN )
+               {
+                   /*
+                    * Use the old values
+                    */
+                if( buttons ) *buttons = joy->tmp_buttons;
+                   if( axes    ) memcpy( axes, joy->tmp_axes, sizeof(float) * joy->num_axes );
+                return;
+               }
+
+               fgWarning( "%s", joy->fname );
+               joy->error = TRUE;
+               return;
+        }
+
+        switch( joy->js.type & ~JS_EVENT_INIT )
+        {
+           case JS_EVENT_BUTTON:
+               if ( joy->js.value == 0 ) /* clear the flag */
+                   joy->tmp_buttons &= ~(1 << joy->js.number);
+           else
+                   joy->tmp_buttons |= (1 << joy->js.number);
+               break;
+
+           case JS_EVENT_AXIS:
+               joy->tmp_axes[ joy->js.number ] = (float) joy->js.value;
+
+               if( axes )
+                   memcpy( axes, joy->tmp_axes, sizeof(float) * joy->num_axes );
+               break;
+        }
+
+        if( buttons )
+               *buttons = joy->tmp_buttons;
+    }
+#   else
+
+    status = read( joy->fd, &joy->js, JS_RETURN );
+
+    if( status != JS_RETURN )
+    {
+        g_warning( joy->fname );
+        joy->error = TRUE;
+        return;
+    }
+
+    if( buttons )
+#       ifdef __FreeBSD__
+        *buttons = (joy->js.b1 ? 1 : 0) | (joy->js.b2 ? 2 : 0);
+#       else
+        *buttons = joy->js.buttons;
+#       endif
+
+    if( axes )
+    {
+        axes[ 0 ] = (float) joy->js.x;
+        axes[ 1 ] = (float) joy->js.y;
+    }
+#   endif
+#endif
+}
+
+/*
+ * Correct the joystick axis data
+ */
+static float fghJoystickFudgeAxis( SFG_Joystick* joy, float value, int axis )
+{
+    if( value < joy->center[ axis ] )
+    {
+        float xx = (value - joy->center[ axis ]) / (joy->center[ axis ] - joy->min[ axis ]);
+
+        if( xx < -joy->saturate[ axis ] )
+               return( -1.0f );
+
+        if( xx > -joy->dead_band [ axis ] )
+               return(  0.0f );
+
+        xx = (xx + joy->dead_band[ axis ]) / (joy->saturate[ axis ] - joy->dead_band[ axis ]);
+
+        return( ( xx < -1.0f ) ? -1.0f : xx );
+    }
+    else
+    {
+        float xx = (value - joy->center [ axis ]) / (joy->max[ axis ] - joy->center[ axis ]);
+
+        if( xx > joy->saturate[ axis ] )
+            return 1.0f ;
+
+        if( xx < joy->dead_band[ axis ] )
+               return 0.0f ;
+
+        xx = (xx - joy->dead_band[ axis ]) / (joy->saturate[ axis ] - joy->dead_band[ axis ]);
+
+        return( ( xx > 1.0f ) ? 1.0f : xx );
+    }
+}
+
+/*
+ * Read the corrected joystick data
+ */
+static void fghJoystickRead( SFG_Joystick* joy, int* buttons, float* axes )
+{
+    float raw_axes[ _JS_MAX_AXES ];
+    int  i;
+
+    if( joy->error )
+    {
+        if( buttons )
+            *buttons = 0;
+
+        if( axes )
+            for ( i=0; i<joy->num_axes ; i++ )
+                axes[ i ] = 0.0f ;
+    }
+
+    fghJoystickRawRead( joy, buttons, raw_axes );
+
+    if( axes )
+        for( i=0 ; i<joy->num_axes ; i++ )
+            axes[ i ] = fghJoystickFudgeAxis( joy, raw_axes[ i ], i );
+}
+
+/*
+ * Happy happy happy joy joy joy (happy new year toudi :D)
+ */
+static void fghJoystickOpen( SFG_Joystick* joy )
+{
+#ifdef WIN32
+    JOYCAPS jsCaps;
+    int     i;
+
+    joy->js.dwFlags = JOY_RETURNALL;
+    joy->js.dwSize  = sizeof( joy->js );
+
+    memset( &jsCaps, 0, sizeof(jsCaps) );
+
+    joy->error    = (joyGetDevCaps( joy->js_id, &jsCaps, sizeof(jsCaps) ) != JOYERR_NOERROR);
+    joy->num_axes = (jsCaps.wNumAxes < _JS_MAX_AXES ) ? jsCaps.wNumAxes : _JS_MAX_AXES;
+
+    /*
+     * WARNING - Fall through case clauses!!
+     */
+    switch( joy->num_axes )
+    {
+    case 6 : joy->min[ 5 ] = (float) jsCaps.wVmin; joy->max[ 5 ] = (float) jsCaps.wVmax;
+    case 5 : joy->min[ 4 ] = (float) jsCaps.wUmin; joy->max[ 4 ] = (float) jsCaps.wUmax;
+    case 4 : joy->min[ 3 ] = (float) jsCaps.wRmin; joy->max[ 3 ] = (float) jsCaps.wRmax;
+    case 3 : joy->min[ 2 ] = (float) jsCaps.wZmin; joy->max[ 2 ] = (float) jsCaps.wZmax;
+    case 2 : joy->min[ 1 ] = (float) jsCaps.wYmin; joy->max[ 1 ] = (float) jsCaps.wYmax;
+    case 1 : joy->min[ 0 ] = (float) jsCaps.wXmin; joy->max[ 0 ] = (float) jsCaps.wXmax; break;
+
+    /*
+     * I guess we have no axes at all
+     */
+    default: joy->error = TRUE; break;
+    }
+
+    /*
+     * Guess all the rest judging on the axes extremals
+     */
+    for( i=0 ; i<joy->num_axes ; i++ )
+    {
+        joy->center   [ i ] = (joy->max[i] + joy->min[i]) * 0.5f;
+        joy->dead_band[ i ] = 0.0f;
+        joy->saturate [ i ] = 1.0f;
+    }
+
+#else
+#   ifdef __FreeBSD__
+    int   buttons[ _JS_MAX_AXES ];
+    float axes[ _JS_MAX_AXES ];
+    int   noargs, in_no_axes;
+    char  joyfname[ 1024 ];
+    FILE* joyfile;
+#   else
+#       ifndef JS_NEW
+    int counter;
+#       endif
+#   endif
+    int i;
+
+    /*
+     * Default for older Linux systems.
+     */
+    joy->num_axes    =  2;
+    joy->num_buttons = 32;
+
+#   ifdef JS_NEW
+    for( i=0 ; i<_JS_MAX_AXES ; i++ )
+        joy->tmp_axes[ i ] = 0.0f ;
+
+    joy->tmp_buttons = 0 ;
+#   endif
+
+    joy->fd = open( joy->fname, O_RDONLY );
+
+    joy->error = (joy->fd < 0);
+
+    if( joy->error )
+        return;
+
+#   ifdef __FreeBSD__
+    fghJoystickRawRead(joy, buttons, axes );
+    joy->error = axes[ 0 ] < -1000000000.0f;
+    if( joy->error )
+      return ;
+
+    sprintf( joyfname, "%s/.joy%drc", g_getenv( "HOME" ), joy->id );
+
+    joyfile = fopen( joyfname, "r" );
+    joy->error = (joyfile == NULL);
+    if( joy->error )
+      return;
+
+    noargs = fscanf(
+        joyfile, "%d%f%f%f%f%f%f",
+        &in_no_axes,
+        &joy->min[ 0 ], &joy->center[ 0 ], &joy->max[ 0 ],
+        &joy->min[ 1 ], &joy->center[ 1 ], &joy->max[ 1 ]
+    );
+
+    joy->error = (noargs != 7) || (in_no_axes != _JS_MAX_AXES);
+    fclose( joyfile );
+    if( joy->error )
+      return;
+
+    for( i=0 ; i<_JS_MAX_AXES ; i++ )
+    {
+        joy->dead_band[ i ] = 0.0f;
+        joy->saturate [ i ] = 1.0f;
+    }
+#   else
+
+    /*
+     * Set the correct number of axes for the linux driver
+     */
+#       ifdef JS_NEW
+    ioctl( joy->fd, JSIOCGAXES   , &joy->num_axes    );
+    ioctl( joy->fd, JSIOCGBUTTONS, &joy->num_buttons );
+    fcntl( joy->fd, F_SETFL, O_NONBLOCK );
+
+#       endif
+
+    /*
+     * The Linux driver seems to return 512 for all axes
+     * when no stick is present - but there is a chance
+     * that could happen by accident - so it's gotta happen
+     * on both axes for at least 100 attempts.
+     *
+     * PWO: shouldn't be that done somehow wiser on the kernel level?
+     */
+#       ifndef JS_NEW
+    counter = 0 ;
+
+    do
+    { 
+        fghJoystickRawRead( joy, NULL, joy->center );
+        counter++;
+    } while( !joy->error && counter < 100 && joy->center[ 0 ] == 512.0f && joy->center[ 1 ] == 512.0f );
+   
+    if( counter >= 100 )
+        joy->error = TRUE;
+#       endif
+
+    for( i=0 ; i<_JS_MAX_AXES ; i++ )
+    {
+#       ifdef JS_NEW
+        joy->max   [ i ] =  32767.0f;
+        joy->center[ i ] =      0.0f;
+        joy->min   [ i ] = -32767.0f;
+#       else
+        joy->max[ i ] = joy->center[ i ] * 2.0f;
+        joy->min[ i ] = 0.0f;
+#       endif
+        joy->dead_band[ i ] = 0.0f ;
+        joy->saturate [ i ] = 1.0f ;
+    }
+#   endif
+#endif
+}
+
+/*
+ *
+ */
+void fgJoystickInit( int ident )
+{
+    /*
+     * Make sure we don't get reinitialized
+     */
+    if( fgJoystick != NULL )
+        fgError( "illegal attemp to initialize joystick device" );
+
+    /*
+     * Have the global joystick structure created
+     */
+    fgJoystick = calloc( sizeof(SFG_Joystick), 1 );
+
+#ifdef WIN32
+    switch( ident )
+    {
+    case 0:  fgJoystick->js_id    = JOYSTICKID1; fghJoystickOpen( fgJoystick ); break;
+    case 1:  fgJoystick->js_id    = JOYSTICKID2; fghJoystickOpen( fgJoystick ); break;
+    default: fgJoystick->num_axes = 0; fgJoystick->error = TRUE;                break;
+    }
+#else
+
+#   ifdef __FreeBSD__
+    fgJoystick->id = ident;
+    sprintf( fgJoystick->fname, "/dev/joy%d", ident );
+#   else
+    sprintf( fgJoystick->fname, "/dev/js%d", ident );
+#   endif
+
+    /*
+     * Let's try opening the joystick device now:
+     */
+    fghJoystickOpen( fgJoystick );
+#endif
+}
+
+/*
+ *
+ */
+void fgJoystickClose( void )
+{
+    if( fgJoystick == NULL )
+        fgError( "illegal attempt to deinitialize joystick device" );
+
+#ifndef WIN32
+    if( fgJoystick->error != TRUE )
+        close( fgJoystick->fd );
+#endif
+
+    free ( fgJoystick ) ;
+    fgJoystick = NULL ;  /* show joystick has been deinitialized */
+}
+
+/*
+ * Polls the joystick and executes the joystick callback hooked to the
+ * window specified in the function's parameter:
+ */
+void fgJoystickPollWindow( SFG_Window* window )
+{
+    float axes[ _JS_MAX_AXES ];
+    int buttons;
+
+    /*
+     * Make sure the joystick device is initialized, the window seems valid
+     * and that there is a joystick callback hooked to it:
+     */
+    freeglut_return_if_fail( fgJoystick != NULL && window != NULL );
+    freeglut_return_if_fail( window->Callbacks.Joystick != NULL );
+
+    /*
+     * Poll the joystick now:
+     */
+    fghJoystickRead( fgJoystick, &buttons, axes );
+
+    /*
+     * Execute the freeglut joystick callback now
+     */
+    window->Callbacks.Joystick(
+        buttons,
+        (int) (axes[ 0 ] * 1000.0f),
+        (int) (axes[ 1 ] * 1000.0f),
+        (int) (axes[ 2 ] * 1000.0f)
+    );
+}
+
+/*
+ * PWO: These jsJoystick class methods have not been implemented.
+ *      We might consider adding such functions to freeglut-2.0.
+ */
+#if 0
+  int  getNumAxes () { return num_axes ; }
+  int  notWorking () { return error ;    }
+
+  float getDeadBand ( int axis )             { return dead_band [ axis ] ; }
+  void  setDeadBand ( int axis, float db )   { dead_band [ axis ] = db   ; }
+
+  float getSaturation ( int axis )           { return saturate [ axis ]  ; }
+  void  setSaturation ( int axis, float st ) { saturate [ axis ] = st    ; }
+
+  void setMinRange ( float *axes ) { memcpy ( min   , axes, num_axes * sizeof(float) ) ; }
+  void setMaxRange ( float *axes ) { memcpy ( max   , axes, num_axes * sizeof(float) ) ; }
+  void setCenter   ( float *axes ) { memcpy ( center, axes, num_axes * sizeof(float) ) ; }
+
+  void getMinRange ( float *axes ) { memcpy ( axes, min   , num_axes * sizeof(float) ) ; }
+  void getMaxRange ( float *axes ) { memcpy ( axes, max   , num_axes * sizeof(float) ) ; }
+  void getCenter   ( float *axes ) { memcpy ( axes, center, num_axes * sizeof(float) ) ; }
+#endif
+
+/*** END OF FILE ***/
+
+
+
+
diff --git a/src/freeglut_main.c b/src/freeglut_main.c
new file mode 100644 (file)
index 0000000..1c11f0d
--- /dev/null
@@ -0,0 +1,1797 @@
+/*
+ * freeglut_main.c
+ *
+ * The windows message processing 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-main"
+
+#include "../include/GL/freeglut.h"
+#include "freeglut_internal.h"
+
+/*
+ * TODO BEFORE THE STABLE RELEASE:
+ *
+ * There are some issues concerning window redrawing under X11, and maybe
+ * some events are not handled. The Win32 version lacks some more features,
+ * but seems acceptable for not demanding purposes.
+ *
+ * Need to investigate why the X11 version breaks out with an error when
+ * closing a window (using the window manager, not glutDestroyWindow)...
+ */
+
+/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
+
+/*
+ * Calls a window's redraw method. This is used when
+ * a redraw is forced by the incoming window messages.
+ */
+
+static void fghRedrawWindowByHandle
+#if TARGET_HOST_UNIX_X11
+    ( Window handle )
+#elif TARGET_HOST_WIN32
+    ( HWND handle )
+#endif
+{
+    /*
+     * Find the window we have to redraw...
+     */
+    SFG_Window* window = fgWindowByHandle( handle );
+    freeglut_return_if_fail( window != NULL );
+
+    /*
+     * Check if there is a display callback hooked to it
+     */
+    freeglut_return_if_fail( window->Callbacks.Display != NULL );
+
+    /*
+     * Return if the window is not visible
+     */
+    freeglut_return_if_fail( window->State.Visible == TRUE );
+
+    /*
+     * Set the window as the current one.
+     */
+    fgSetWindow( window );
+
+    /*
+     * Do not exagerate with the redisplaying
+     */
+    window->State.Redisplay = FALSE;
+
+    /*
+     * Have the callback executed now. The buffers should
+     * be swapped by the glutSwapBuffers() execution inside
+     * the callback itself.
+     */
+
+    window->Callbacks.Display();
+}
+
+/*
+ * Handle a window configuration change. When no reshape
+ * callback is hooked, the viewport size is updated to
+ * match the new window size.
+ */
+static void fghReshapeWindowByHandle
+#if TARGET_HOST_UNIX_X11
+    ( Window handle, int width, int height )
+#elif TARGET_HOST_WIN32
+    ( HWND handle, int width, int height )
+#endif
+{
+    /*
+     * Find the window that received the reshape event
+     */
+    SFG_Window* window = fgWindowByHandle( handle );
+    freeglut_return_if_fail( window != NULL );
+
+    /*
+     * Remember about setting the current window...
+     */
+    fgSetWindow( window );
+
+    /*
+     * Check if there is a reshape callback hooked
+     */
+    if( window->Callbacks.Reshape != NULL )
+    {
+        /*
+         * OKi, have it called immediately
+         */
+        window->Callbacks.Reshape( width, height );
+    }
+    else
+    {
+        /*
+         * Otherwise just resize the viewport
+         */
+        glViewport( 0, 0, width, height );
+    }
+
+    /*
+     * Force a window redraw.  In Windows at least this is only a partial solution:  if the
+     * window is increasing in size in either dimension, the already-drawn part does not get
+     * drawn again and things look funny.  But without this we get this bad behaviour whenever
+     * we resize the window.
+     */
+    window->State.Redisplay = TRUE ;
+}
+
+/*
+ * A static helper function to execute display callback for a window
+ */
+static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator )
+{
+#if TARGET_HOST_UNIX_X11
+    /*
+     * Check if there is an idle callback hooked
+     */
+    if( (window->Callbacks.Display != NULL) &&
+        (window->State.Redisplay == TRUE) &&
+        (window->State.Visible == TRUE) )
+    {
+        /*
+         * OKi, this is the case: have the window set as the current one
+         */
+        fgSetWindow( window );
+
+        /*
+         * Do not exagerate with the redisplaying
+         */
+        window->State.Redisplay = FALSE;
+
+        /*
+         * And execute the display callback immediately after
+         */
+        window->Callbacks.Display();
+    }
+
+#elif TARGET_HOST_WIN32
+
+    /*
+     * Do we need to explicitly resize the window?
+     */
+    if( window->State.NeedToResize )
+    {
+        fgSetWindow( window );
+
+        fghReshapeWindowByHandle( 
+            window->Window.Handle,
+            glutGet( GLUT_WINDOW_WIDTH ),
+            glutGet( GLUT_WINDOW_HEIGHT )
+        );
+
+        /*
+         * Never ever do that again:
+         */
+        window->State.NeedToResize = FALSE;
+    }
+
+    /*
+     * This is done in a bit different way under Windows
+     */
+    if( (window->Callbacks.Display != NULL) &&
+        (window->State.Redisplay == TRUE) &&
+        (window->State.Visible == TRUE) )
+    {
+      /*
+       * Do not exagerate with the redisplaying
+       */
+      window->State.Redisplay = FALSE;
+
+      RedrawWindow( 
+        window->Window.Handle, NULL, NULL, 
+        RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_UPDATENOW
+       );
+    }
+
+#endif
+
+    /*
+     * Process this window's children (if any)
+     */
+    fgEnumSubWindows( window, fghcbDisplayWindow, enumerator );
+}
+
+/*
+ * Make all windows perform a display call
+ */
+static void fghDisplayAll( void )
+{
+    SFG_Enumerator enumerator;
+
+    /*
+     * Uses a method very similiar for fgWindowByHandle...
+     */
+    enumerator.found = FALSE;
+    enumerator.data  =  NULL;
+
+    /*
+     * Start the enumeration now:
+     */
+    fgEnumWindows( fghcbDisplayWindow, &enumerator );
+}
+
+/*
+ * Window enumerator callback to check for the joystick polling code
+ */
+static void fghcbCheckJoystickPolls( SFG_Window *window, SFG_Enumerator *enumerator )
+{
+    long int checkTime = fgElapsedTime();
+
+    /*
+     * Check if actually need to do the poll for the currently enumerated window:
+     */
+    if( window->State.JoystickLastPoll + window->State.JoystickPollRate >= checkTime )
+    {
+        /*
+         * Yeah, that's it. Poll the joystick...
+         */
+        fgJoystickPollWindow( window );
+
+        /*
+         * ...and reset the polling counters:
+         */
+        window->State.JoystickLastPoll = checkTime;
+    }
+
+    /*
+     * Process this window's children (if any)
+     */
+    fgEnumSubWindows( window, fghcbCheckJoystickPolls, enumerator );
+}
+
+/*
+ * Check all windows for joystick polling
+ */
+static void fghCheckJoystickPolls( void )
+{
+    SFG_Enumerator enumerator;
+
+    /*
+     * Uses a method very similiar for fgWindowByHandle...
+     */
+    enumerator.found = FALSE;
+    enumerator.data  =  NULL;
+
+    /*
+     * Start the enumeration now:
+     */
+    fgEnumWindows( fghcbCheckJoystickPolls, &enumerator );
+}
+
+/*
+ * Check the global timers
+ */
+static void fghCheckTimers( void )
+{
+    long checkTime = fgElapsedTime();
+    SFG_Timer *timer, *next;
+    SFG_List timedOut;
+
+    fgListInit(&timedOut);
+
+    /*
+     * For every timer that is waiting for triggering
+     */
+    for( timer = fgState.Timers.First; timer; timer = next )
+    {
+       next = timer->Node.Next;
+
+        /*
+         * Check for the timeout:
+         */
+        if( timer->TriggerTime <= checkTime )
+        {
+            /*
+             * Add the timer to the timed out timers list
+             */
+           fgListRemove( &fgState.Timers, &timer->Node );
+            fgListAppend( &timedOut, &timer->Node );
+        }
+    }
+
+    /*
+     * Now feel free to execute all the hooked and timed out timer callbacks
+     * And delete the timed out timers...
+     */
+    while ( (timer = timedOut.First) )
+    {
+        if( timer->Callback != NULL )
+            timer->Callback( timer->ID );
+       fgListRemove( &timedOut, &timer->Node );
+        free( timer );
+    }
+}
+
+
+/*
+ * Elapsed Time
+ */
+long fgElapsedTime( void )
+{
+#if TARGET_HOST_UNIX_X11
+       struct timeval now;
+       long elapsed;
+
+       gettimeofday( &now, NULL );
+
+       elapsed = (now.tv_usec - fgState.Time.Value.tv_usec) / 1000;
+       elapsed += (now.tv_sec - fgState.Time.Value.tv_sec) * 1000;
+
+       return( elapsed );
+#elif TARGET_HOST_WIN32
+  return (timeGetTime() - fgState.Time.Value);
+#endif
+}
+
+/*
+ * Error Messages.
+ */
+void fgError( const char *fmt, ... )
+{
+    va_list ap;
+
+    va_start( ap, fmt );
+
+    fprintf( stderr, "freeglut: ");
+    vfprintf( stderr, fmt, ap );
+    fprintf( stderr, "\n" );
+
+    va_end( ap );
+
+    exit( 1 );
+}
+
+void fgWarning( const char *fmt, ... )
+{
+    va_list ap;
+
+    va_start( ap, fmt );
+
+    fprintf( stderr, "freeglut: ");
+    vfprintf( stderr, fmt, ap );
+    fprintf( stderr, "\n" );
+
+    va_end( ap );
+}
+
+/*
+ * Clean up on exit
+ */
+static void fgCleanUpGlutsMess( void ) 
+{
+  int i;
+
+  i = 0;
+
+  if ( fgStructure.Windows.First != NULL ) 
+  {
+    SFG_Window *win = fgStructure.Windows.First ;
+    glEnd();
+    glFinish();
+    glFlush();
+    while ( win != NULL )
+    {
+      SFG_Window *temp_win = win->Node.Next ;
+      fgDestroyWindow ( win, FALSE ) ;
+      win = temp_win ;
+    }
+  }
+
+#if 0
+  /* these are pointers to external handles */
+
+  __glutWindowListSize    = 0;
+  __glutStaleWindowList   = NULL;
+  __glutWindowList        = NULL;
+  __glutCurrentWindow     = NULL;
+
+  /* make sure we no longer have a GL context */
+
+  if ( wglGetCurrentContext() != NULL ) 
+  {
+    wglDeleteContext( wglGetCurrentContext() );
+  }
+
+  hInstance = GetModuleHandle(NULL);
+  UnregisterClass( classname, hInstance );
+
+  /* clean up allocated timer memory */
+
+  tList = __glutTimerList;
+  i = 0;
+
+  while ( __glutTimerList ) 
+  {
+    i++;
+    tList = __glutTimerList;
+    
+    if ( __glutTimerList )
+      __glutTimerList = __glutTimerList->next;
+
+    if ( tList )
+      free( tList );
+  }
+#endif
+}
+
+
+/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
+
+/*
+ * Executes a single iteration in the freeglut processing loop.
+ */
+void FGAPIENTRY glutMainLoopEvent( void )
+{
+#if TARGET_HOST_UNIX_X11
+  SFG_Window* window;
+  XEvent event;
+  int modifiers;
+
+  /*
+   * This code was repeated constantly, so here it goes into a definition:
+   */
+# define GETWINDOW(a) window = fgWindowByHandle( event.a.window );if( window == NULL ) break;
+# define GETMOUSE(a) window->State.MouseX = event.a.x; window->State.MouseY = event.a.y;
+
+  /*
+   * Make sure the display has been created etc.
+   */
+  freeglut_assert_ready;
+
+  /*
+   * Do we have any event messages pending?
+   */
+  if( XPending( fgDisplay.Display ) )
+  {
+    /*
+     * Grab the next event to be processed...
+     */
+    XNextEvent( fgDisplay.Display, &event );
+    window = fgWindowByHandle ( event.xany.window ) ;
+
+    /*
+     * Check the event's type
+     */
+    switch( event.type )
+    {
+    case CreateNotify:
+      /*
+       * The window creation confirmation
+       */
+      break;
+
+    case DestroyNotify:
+      /*
+       * This is sent to confirm the XDestroyWindow call.
+       */
+      /*
+       * Call the window closure callback, remove from the structure, etc.
+       */
+      fgStructure.Window = window ;
+/*      fgAddToWindowDestroyList ( window, FALSE ); */
+
+      break;
+
+    case ClientMessage:
+      /*
+       * Destroy the window when the WM_DELETE_WINDOW message arrives
+       */
+      if( (Atom) event.xclient.data.l[ 0 ] == fgDisplay.DeleteWindow )
+      {
+        fgStructure.Window = window ;
+
+        /*
+         * Call the XWindows functions to close the window
+         */
+        fgCloseWindow ( window ) ;
+
+        /*
+         * Call the window closure callback, remove from the structure, etc.
+         */
+        fgAddToWindowDestroyList ( window, FALSE );
+      }
+      break;
+
+    case UnmapNotify:
+      /*
+       * A window of ours has been unmapped...
+       */
+      break;
+
+    case Expose:
+      /*
+       * We are too dumb to process partial exposes...
+       */
+      if( event.xexpose.count == 0 )
+          fghRedrawWindowByHandle( window->Window.Handle );
+      break;
+
+    case ConfigureNotify:
+      /*
+       * The window gets resized
+       */
+      fghReshapeWindowByHandle(
+          event.xconfigure.window,
+          event.xconfigure.width,
+          event.xconfigure.height
+      );
+      break;
+
+    case MappingNotify:
+      /*
+       * Have the client's keyboard knowledge updated (xlib.ps,
+       * page 206, says that's a good thing to do)
+       */
+      XRefreshKeyboardMapping( (XMappingEvent *) &event );
+      break;
+
+    case VisibilityNotify:
+      {
+        /*
+         * The window's visiblity might have changed
+         */
+        /*
+         * Break now if no window status callback has been hooked to that window
+         */
+        if( window->Callbacks.WindowStatus == NULL )
+            break;
+
+        /*
+         * We're going to send a callback to a window. Make it current.
+         */
+        fgSetWindow( window );
+
+        /*
+         * Sending this event, the X server can notify us that the window has just
+         * acquired one of the three possible visibility states: VisibilityUnobscured,
+         * VisibilityPartiallyObscured or VisibilityFullyObscured
+         */
+        switch( event.xvisibility.state )
+        {
+        case VisibilityUnobscured:
+          /*
+           * We are fully visible...
+           */
+          window->Callbacks.WindowStatus( GLUT_FULLY_RETAINED );
+          window->State.Visible = TRUE;
+          break;
+
+        case VisibilityPartiallyObscured:
+          /*
+           * The window is partially visible
+           */
+          window->Callbacks.WindowStatus( GLUT_PARTIALLY_RETAINED );
+          window->State.Visible = TRUE;
+          break;
+
+        case VisibilityFullyObscured:
+          /*
+           * The window is totally obscured
+           */
+          window->Callbacks.WindowStatus( GLUT_FULLY_COVERED );
+          window->State.Visible = FALSE;
+          break;
+        }
+      }
+      break;
+
+    case EnterNotify:
+      {
+        /*
+         * Mouse is over one of our windows
+         */
+        GETMOUSE( xcrossing );
+
+        /*
+         * Is there an entry callback hooked to the window?
+         */
+        if( window->Callbacks.Entry != NULL )
+        {
+          /*
+           * Yeah. Notify the window about having the mouse cursor over
+           */
+          window->Callbacks.Entry( GLUT_ENTERED );
+        }
+      }
+      break;
+
+    case LeaveNotify:
+      {
+        /*
+         * Mouse is no longer over one of our windows
+         */
+        GETMOUSE( xcrossing );
+
+        /*
+         * Is there an entry callback hooked to the window?
+         */
+        if( window->Callbacks.Entry != NULL )
+        {
+          /*
+           * Yeah. Notify the window about having the mouse cursor over
+           */
+          window->Callbacks.Entry( GLUT_LEFT );
+        }
+      }
+      break;
+
+    case MotionNotify:
+      {
+        /*
+         * The mouse cursor was moved...
+         */
+        GETMOUSE( xmotion );
+
+        /*
+         * Set the current window
+         */
+        fgStructure.Window = window ;
+
+        /*
+         * What kind of a movement was it?
+         */
+        if( (event.xmotion.state & Button1Mask) || (event.xmotion.state & Button2Mask) ||
+            (event.xmotion.state & Button3Mask) || (event.xmotion.state & Button4Mask) ||
+            (event.xmotion.state & Button5Mask) )
+        {
+          /*
+           * A mouse button was pressed during the movement...
+           * Is there a motion callback hooked to the window?
+           */
+          if( window->Callbacks.Motion != NULL )
+          {
+            /*
+             * Yup. Have it executed immediately
+             */
+            window->Callbacks.Motion( event.xmotion.x, event.xmotion.y );
+          }
+        }
+        else
+        {
+          /*
+           * Otherwise it was a passive movement...
+           */
+          if( window->Callbacks.Passive != NULL )
+          {
+            /*
+             * That's right, and there is a passive callback, too.
+             */
+            window->Callbacks.Passive( event.xmotion.x, event.xmotion.y );
+          }
+        }
+      }
+      break;
+
+    case ButtonRelease:
+    case ButtonPress:
+      {
+        GLboolean pressed = TRUE ;
+        int button;
+
+        if ( event.type == ButtonRelease ) pressed = FALSE ;
+
+        /*
+         * A mouse button has been pressed or released. Traditionally,
+         * break if the window was found within the freeglut structures.
+         */
+        GETMOUSE( xbutton );
+
+        /*
+         * GLUT API assumes that you can't have more than three mouse buttons, so:
+         */
+        switch( event.xbutton.button )
+        {
+        /*
+         * WARNING: this might be wrong, if we only have two mouse buttons,
+         *          Button2 might mean the right button, isn't that right?
+         */
+        case Button1:   button = GLUT_LEFT_BUTTON;   break;
+        case Button2:   button = GLUT_MIDDLE_BUTTON; break;
+        case Button3:   button = GLUT_RIGHT_BUTTON;  break;
+        default:        button = -1;                 break;
+        }
+
+        /*
+         * Skip the unwanted mouse buttons...
+         */
+        if( button == -1 )
+          break;
+
+        /*
+         * Do not execute the application's mouse callback if a menu is hooked to this button.
+         * In that case an appropriate private call should be generated.
+         * 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
+         */
+        if ( window->ActiveMenu != NULL )  /* Window has an active menu, it absorbs any mouse click */
+        {
+          if ( fgCheckActiveMenu ( window, window->ActiveMenu ) == TRUE )  /* Inside the menu, invoke the callback and deactivate the menu*/
+          {
+            /* Save the current window and menu and set the current window to the window whose menu this is */
+            SFG_Window *save_window = fgStructure.Window ;
+            SFG_Menu *save_menu = fgStructure.Menu ;
+            fgSetWindow ( window ) ;
+            fgStructure.Menu = window->ActiveMenu ;
+
+            /* Execute the menu callback */
+            fgExecuteMenuCallback ( window->ActiveMenu ) ;
+            fgDeactivateMenu ( window ) ;
+
+            /* Restore the current window and menu */
+            fgSetWindow ( save_window ) ;
+            fgStructure.Menu = save_menu ;
+          }
+          else  /* Outside the menu, deactivate the menu if it's a downclick */
+          {
+            if ( pressed == TRUE ) fgDeactivateMenu ( window ) ;
+          }
+
+          /*
+           * Let's make the window redraw as a result of the mouse click and menu activity.
+           */
+          window->State.Redisplay = TRUE ;
+
+          break ;
+        }
+
+        /*
+         * No active menu, let's check whether we need to activate one.
+         */
+        if ( ( window->Menu[ button ] != NULL ) && ( pressed == TRUE ) )
+        {
+          /*
+           * Let's make the window redraw as a result of the mouse click.
+           */
+          window->State.Redisplay = TRUE ;
+
+          /*
+           * Activate the appropriate menu structure...
+           */
+          fgActivateMenu( window, button );
+
+          break;
+        }
+
+        /*
+         * Check if there is a mouse callback hooked to the window
+         */
+        if( window->Callbacks.Mouse == NULL )
+          break;
+
+        /*
+         * Set the current window
+         */
+        fgSetWindow( window );
+
+        /*
+         * Remember the current modifiers state
+         */
+        modifiers = 0;
+        if (event.xbutton.state & (ShiftMask|LockMask))
+          modifiers |= GLUT_ACTIVE_SHIFT;
+        if (event.xbutton.state & ControlMask)
+          modifiers |= GLUT_ACTIVE_CTRL;
+        if (event.xbutton.state & Mod1Mask)
+          modifiers |= GLUT_ACTIVE_ALT;
+        window->State.Modifiers = modifiers;
+
+        /*
+         * Finally execute the mouse callback
+         */
+        window->Callbacks.Mouse(
+            button,
+            event.type == ButtonPress ? GLUT_DOWN : GLUT_UP,
+            event.xbutton.x,
+            event.xbutton.y
+        );
+
+        /*
+         * Trash the modifiers state
+         */
+        window->State.Modifiers = 0xffffffff;
+      }
+      break;
+
+    case KeyRelease:
+    case KeyPress:
+      {
+        FGCBkeyboard keyboard_cb;
+        FGCBspecial special_cb;
+
+        /*
+         * A key has been pressed, find the window that had the focus:
+         */
+        GETMOUSE( xkey );
+
+        if( event.type == KeyPress )
+        {
+          keyboard_cb = window->Callbacks.Keyboard;
+          special_cb = window->Callbacks.Special;
+        }
+        else
+        {
+          keyboard_cb = window->Callbacks.KeyboardUp;
+          special_cb = window->Callbacks.SpecialUp;
+        }
+
+        /*
+         * Is there a keyboard/special callback hooked for this window?
+         */
+        if( (keyboard_cb != NULL) || (special_cb != NULL) )
+        {
+          XComposeStatus composeStatus;
+          char asciiCode[ 32 ];
+          KeySym keySym;
+          int len;
+
+          /*
+           * Check for the ASCII/KeySym codes associated with the event:
+           */
+          len = XLookupString( &event.xkey, asciiCode, sizeof(asciiCode), &keySym, &composeStatus );
+
+          /*
+           * Get ready to calling the keyboard/special callbacks
+           */
+          fgSetWindow( window );
+
+          /*
+           * GLUT API tells us to have two separate callbacks...
+           */
+          if( len > 0 )
+          {
+            /*
+             * ...one for the ASCII translateable keypresses...
+             */
+            if( keyboard_cb != NULL )
+            {
+              /*
+               * Remember the current modifiers state
+               */
+              modifiers = 0;
+              if (event.xkey.state & (ShiftMask|LockMask))
+                  modifiers |= GLUT_ACTIVE_SHIFT;
+              if (event.xkey.state & ControlMask)
+                  modifiers |= GLUT_ACTIVE_CTRL;
+              if (event.xkey.state & Mod1Mask)
+                  modifiers |= GLUT_ACTIVE_ALT;
+              window->State.Modifiers = modifiers;
+
+              /*
+               * Execute the callback
+               */
+              keyboard_cb( asciiCode[ 0 ], event.xkey.x, event.xkey.y );
+
+              /*
+               * Trash the modifiers state
+               */
+              window->State.Modifiers = 0xffffffff;
+            }
+          }
+          else
+          {
+            int special = -1;
+
+            /*
+             * ...and one for all the others, which need to be translated to GLUT_KEY_Xs...
+             */
+            switch( keySym )
+            {
+            /*
+             * First the function keys come:
+             */
+            case XK_F1:     special = GLUT_KEY_F1;     break;
+            case XK_F2:     special = GLUT_KEY_F2;     break;
+            case XK_F3:     special = GLUT_KEY_F3;     break;
+            case XK_F4:     special = GLUT_KEY_F4;     break;
+            case XK_F5:     special = GLUT_KEY_F5;     break;
+            case XK_F6:     special = GLUT_KEY_F6;     break;
+            case XK_F7:     special = GLUT_KEY_F7;     break;
+            case XK_F8:     special = GLUT_KEY_F8;     break;
+            case XK_F9:     special = GLUT_KEY_F9;     break;
+            case XK_F10:    special = GLUT_KEY_F10;    break;
+            case XK_F11:    special = GLUT_KEY_F11;    break;
+            case XK_F12:    special = GLUT_KEY_F12;    break;
+
+            /*
+             * Then the arrows and stuff:
+             */
+            case XK_Left:   special = GLUT_KEY_LEFT;   break;
+            case XK_Right:  special = GLUT_KEY_RIGHT;  break;
+            case XK_Up:     special = GLUT_KEY_UP;     break;
+            case XK_Down:   special = GLUT_KEY_DOWN;   break;
+
+            case XK_KP_Prior:
+            case XK_Prior:  special = GLUT_KEY_PAGE_UP; break;
+            case XK_KP_Next:
+            case XK_Next:   special = GLUT_KEY_PAGE_DOWN; break;
+            case XK_KP_Home:
+            case XK_Home:   special = GLUT_KEY_HOME;   break;
+            case XK_KP_End:
+            case XK_End:    special = GLUT_KEY_END;    break;
+            case XK_KP_Insert:
+            case XK_Insert: special = GLUT_KEY_INSERT; break;
+            }
+
+            /*
+             * Execute the callback (if one has been specified),
+             * given that the special code seems to be valid...
+             */
+            if( (special_cb != NULL) && (special != -1) )
+            {
+              /*
+               * Remember the current modifiers state
+               */
+              modifiers = 0;
+              if (event.xkey.state & (ShiftMask|LockMask))
+                modifiers |= GLUT_ACTIVE_SHIFT;
+              if (event.xkey.state & ControlMask)
+                modifiers |= GLUT_ACTIVE_CTRL;
+              if (event.xkey.state & Mod1Mask)
+                modifiers |= GLUT_ACTIVE_ALT;
+              window->State.Modifiers = modifiers;
+
+              special_cb( special, event.xkey.x, event.xkey.y );
+
+              /*
+               * Trash the modifiers state
+               */
+              window->State.Modifiers = 0xffffffff;
+            }
+          }
+        }
+      }
+      break;
+    }
+  }
+  else
+  {
+    /*
+     * Have all the timers checked.
+     */
+    fghCheckTimers();
+
+    /*
+     * Poll the joystick and notify all windows that want to be notified...
+     */
+    fghCheckJoystickPolls();
+
+    /*
+     * No messages in the queue, which means we are idling...
+     */
+    if( fgState.IdleCallback != NULL )
+        fgState.IdleCallback();
+
+    /*
+     * Remember about displaying all the windows that have
+     * been marked for a redisplay (possibly in the idle call):
+     */
+    fghDisplayAll();
+  }
+
+#elif TARGET_HOST_WIN32
+
+  MSG stMsg;
+
+  /*
+   * The windows processing is considerably smaller
+   */
+  if( PeekMessage( &stMsg, NULL, 0, 0, PM_NOREMOVE ) )
+  {
+    /*
+     * Grab the message now, checking for WM_QUIT
+     */
+    if( GetMessage( &stMsg, NULL, 0, 0 ) == 0 )
+      fgState.ExecState = GLUT_EXEC_STATE_STOP ;
+
+    /*
+     * Translate virtual-key messages and send them to the window...
+     */
+    TranslateMessage( &stMsg );
+    DispatchMessage( &stMsg );
+  }
+  else
+  {
+    /*
+     * Have all the timers checked.
+     */
+    fghCheckTimers();
+
+    /*
+     * Poll the joystick and notify all windows that want to be notified...
+     */
+    fghCheckJoystickPolls();
+
+    /*
+     * No messages in the queue, which means we are idling...
+     */
+    if( fgState.IdleCallback != NULL )
+      fgState.IdleCallback();
+
+    /*
+     * Remember about displaying all the windows that have
+     * been marked for a redisplay (possibly in the idle call):
+     */
+    fghDisplayAll();
+  }
+#endif
+}
+
+/*
+ * Enters the freeglut processing loop. Stays until the "ExecState" changes to "GLUT_EXEC_STATE_STOP".
+ */
+void FGAPIENTRY glutMainLoop( void )
+{
+#if TARGET_HOST_WIN32
+  SFG_Window *window = fgStructure.Windows.First ;
+#endif
+
+  /*
+   * Make sure the display has been created etc.
+   */
+  freeglut_assert_ready;
+
+#if TARGET_HOST_WIN32
+  /*
+   * Processing before the main loop:  If there is a window which is open and which
+   * has a visibility callback, call it.  I know this is an ugly hack, but I'm not sure
+   * what else to do about it.  Ideally we should leave something uninitialized in the
+   * create window code and initialize it in the main loop, and have that initialization
+   * create a "WM_ACTIVATE" message.  Then we would put the visibility callback code in
+   * the "case WM_ACTIVATE" block below.         - John Fay -- 10/24/02
+   */
+  while ( window != NULL )
+  {
+    if ( window->Callbacks.Visibility != NULL )
+      window->Callbacks.Visibility ( window->State.Visible ) ;
+
+    window = window->Node.Next ;
+  }
+#endif
+
+  /*
+   * Set freeglut to be running
+   */
+  fgState.ExecState = GLUT_EXEC_STATE_RUNNING ;
+
+  /*
+   * Enter the main loop itself.  Inside the loop, process events and check for loop exit.
+   */
+  while ( fgState.ExecState == GLUT_EXEC_STATE_RUNNING )
+  {
+    glutMainLoopEvent () ;
+
+    /*
+     * If an event caused a window to be closed, do the actual closing here
+     */
+    fgCloseWindows () ;
+
+    /*
+     * If there are no more windows open, stop execution
+     */
+    if ( fgStructure.Windows.First == NULL )
+      fgState.ExecState = GLUT_EXEC_STATE_STOP ;
+  }
+
+
+  /*
+   * If we got here by the user closing a window or by the application closing down, there may still be windows open.
+   */
+  fgCleanUpGlutsMess () ;
+
+  /*
+   * Check whether we return to the calling program or simply exit
+   */
+  if ( fgState.ActionOnWindowClose == GLUT_ACTION_EXIT )
+    exit ( 0 ) ;
+
+  /*
+   * When this loop terminates, destroy the display, state and structure
+   * of a freeglut session, so that another glutInit() call can happen
+   */
+  fgDeinitialize();
+}
+
+/*
+ * Leaves the freeglut processing loop.
+ */
+void FGAPIENTRY glutLeaveMainLoop( void )
+{
+  fgState.ExecState = GLUT_EXEC_STATE_STOP ;
+}
+
+/*
+ * The window procedure for handling Win32 events
+ */
+#if TARGET_HOST_WIN32
+LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+{
+    SFG_Window* window = fgWindowByHandle( hWnd );
+    PAINTSTRUCT ps;
+    LONG lRet = 1;
+
+    if ( ( window == NULL ) && ( uMsg != WM_CREATE ) )
+      return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
+
+/*    printf ( "Window %3d message <%04x> %12d %12d\n", window?window->ID:0, uMsg, wParam, lParam ) ; */
+    /*
+     * Check what type of message are we receiving
+     */
+    switch( uMsg )
+    {
+    case WM_CREATE:
+        /*
+         * The window structure is passed as the creation structure paramter...
+         */
+        window = (SFG_Window *) (((LPCREATESTRUCT) lParam)->lpCreateParams);
+        assert( window != NULL );
+
+        /*
+         * We can safely store the window's handle now:
+         */
+        window->Window.Handle = hWnd;
+
+        /*
+         * Get the window's device context
+         */
+        window->Window.Device = GetDC( hWnd );
+
+        /*
+         * Setup the pixel format of our window
+         */
+        fgSetupPixelFormat( window, FALSE, PFD_MAIN_PLANE );
+
+        /*
+         * Create the OpenGL rendering context now
+         */
+        window->Window.Context = wglCreateContext( window->Window.Device );
+
+        /*
+         * Still, we'll be needing to explicitly resize the window
+         */
+        window->State.NeedToResize = TRUE;
+
+        /*
+         * Finally, have the window's device context released
+         */
+        ReleaseDC( window->Window.Handle, window->Window.Device );
+        break;
+
+    case WM_SIZE:
+        /*
+         * We got resized... But check if the window has been already added...
+         */
+        fghReshapeWindowByHandle( hWnd, LOWORD(lParam), HIWORD(lParam) );
+        break;
+#if 0
+    case WM_SETFOCUS: 
+        printf("WM_SETFOCUS: %p\n", window );
+        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
+        break;
+
+    case WM_ACTIVATE: 
+        if (LOWORD(wParam) != WA_INACTIVE)
+        {
+          /* glutSetCursor( fgStructure.Window->State.Cursor ); */
+               printf("WM_ACTIVATE: glutSetCursor( %p, %d)\n", window, window->State.Cursor );
+
+          glutSetCursor( window->State.Cursor );
+        }
+
+        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
+        break;
+#endif
+
+    case WM_SETCURSOR: 
+        /*
+         * Windows seems to need reminding to erase the cursor for NONE.
+         */
+#if 0
+        if ((LOWORD(lParam) == HTCLIENT) &&
+           (fgStructure.Window->State.Cursor == GLUT_CURSOR_NONE))
+         SetCursor( NULL );
+#else
+       /* Set the cursor AND change it for this window class. */
+#      define MAP_CURSOR(a,b) case a: SetCursor( LoadCursor( NULL, b ) ); \
+        break;
+       /* Nuke the cursor AND change it for this window class. */
+#      define ZAP_CURSOR(a,b) case a: SetCursor( NULL ); \
+        break;
+
+        if (LOWORD(lParam) == HTCLIENT)
+         switch( window->State.Cursor )
+         {
+               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_UPARROW   );
+               MAP_CURSOR( GLUT_CURSOR_CROSSHAIR,   IDC_CROSS     );
+               /* MAP_CURSOR( GLUT_CURSOR_NONE,        IDC_NO             ); */
+               ZAP_CURSOR( GLUT_CURSOR_NONE,        NULL          );
+
+               default:
+               MAP_CURSOR( GLUT_CURSOR_UP_DOWN,     IDC_ARROW     );
+         }
+#endif
+       else
+         lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
+       break;
+
+    case WM_SHOWWINDOW:
+        /*
+         * We are now Visible!
+         */
+        window->State.Visible = TRUE;
+        window->State.Redisplay = TRUE;
+        break;
+
+    case WM_PAINT:
+        /*
+         * Start the painting job
+         */
+
+        BeginPaint( hWnd, &ps );
+
+        /*
+         * Call the engine's main frame drawing method
+         */
+        fghRedrawWindowByHandle( hWnd );
+
+        /*
+         * End the painting job, release the device context
+         */
+        EndPaint( hWnd, &ps );
+        break;
+
+    case WM_CLOSE:
+        /*
+         * Make sure we don't close a window with current context active
+         */
+        if( fgStructure.Window == window )
+        {
+            wglMakeCurrent( NULL, NULL );
+            wglDeleteContext( window->Window.Context );
+        }
+
+        /*
+         * Put on a linked list of windows to be removed after all the callbacks have returned
+         */
+        fgAddToWindowDestroyList ( window, FALSE ) ;
+
+        /*
+         * Proceed with the window destruction
+         */
+        DestroyWindow( hWnd );
+        break;
+
+    case WM_DESTROY:
+        /*
+         * The window already got destroyed, so don't bother with it.
+         */
+        return( 0 );
+
+    case WM_MOUSEMOVE:
+    {
+        /*
+         * The mouse cursor has moved. Remember the new mouse cursor's position
+         */
+        window->State.MouseX = LOWORD( lParam );
+        window->State.MouseY = HIWORD( lParam );
+
+        /*
+         * Fallback if there's an active menu hooked to this window
+         */
+        if( window->ActiveMenu != NULL )
+        {
+            /*
+             * Let's make the window redraw as a result of the mouse motion.
+             */
+            window->State.Redisplay = TRUE ;
+
+            break;
+        }
+
+        /*
+         * Remember the current modifiers state.
+         */
+        window->State.Modifiers = 
+            ( ( (GetKeyState( VK_LSHIFT   ) < 0 ) || ( GetKeyState( VK_RSHIFT   ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
+            ( ( (GetKeyState( VK_LCONTROL ) < 0 ) || ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL  : 0 ) |
+            ( ( (GetKeyState( VK_LMENU    ) < 0 ) || ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 0 );
+
+        /*
+         * Check if any of the mouse buttons is pressed...
+         */
+        if( (wParam & MK_LBUTTON) || (wParam & MK_MBUTTON) || (wParam & MK_RBUTTON) )
+        {
+            /*
+             * Yeah, indeed. We need to use the motion callback then:
+             */
+            if( window->Callbacks.Motion != NULL )
+            {
+                /*
+                 * Make sure the current window is set...
+                 */
+                fgSetWindow( window );
+
+                /*
+                 * Execute the active mouse motion callback now
+                 */
+                window->Callbacks.Motion( window->State.MouseX, window->State.MouseY );
+            }
+        }
+        else
+        {
+            /*
+             * All mouse buttons are up, execute the passive mouse motion callback
+             */
+            if( window->Callbacks.Passive != NULL )
+            {
+                /*
+                 * Make sure the current window is set
+                 */
+                fgSetWindow( window );
+
+                /*
+                 * Execute the passive mouse motion callback
+                 */
+                window->Callbacks.Passive( window->State.MouseX, window->State.MouseY );
+            }
+        }
+
+        /*
+         * Thrash the current modifiers state now
+         */
+        window->State.Modifiers = 0xffffffff;
+    }
+    break;
+
+    case WM_LBUTTONDOWN:
+    case WM_MBUTTONDOWN:
+    case WM_RBUTTONDOWN:
+    case WM_LBUTTONUP:
+    case WM_MBUTTONUP:
+    case WM_RBUTTONUP:
+    {
+        GLboolean pressed = TRUE;
+        int button;
+
+        /*
+         * The mouse cursor has moved. Remember the new mouse cursor's position
+         */
+        window->State.MouseX = LOWORD( lParam );
+        window->State.MouseY = HIWORD( lParam );
+
+        /*
+         * We're curious about the GLUT API button name...
+         */
+        switch( uMsg )
+        {
+        case WM_LBUTTONDOWN: pressed = TRUE;  button = GLUT_LEFT_BUTTON;   break;
+        case WM_MBUTTONDOWN: pressed = TRUE;  button = GLUT_MIDDLE_BUTTON; break;
+        case WM_RBUTTONDOWN: pressed = TRUE;  button = GLUT_RIGHT_BUTTON;  break;
+        case WM_LBUTTONUP:   pressed = FALSE; button = GLUT_LEFT_BUTTON;   break;
+        case WM_MBUTTONUP:   pressed = FALSE; button = GLUT_MIDDLE_BUTTON; break;
+        case WM_RBUTTONUP:   pressed = FALSE; button = GLUT_RIGHT_BUTTON;  break;
+        default:             pressed = FALSE; button = -1;                 break;
+        }
+
+        /*
+         * The left and right mouse buttons might have been swapped...
+         */
+        if( GetSystemMetrics( SM_SWAPBUTTON ) )
+            if( button == GLUT_LEFT_BUTTON ) button = GLUT_RIGHT_BUTTON;
+            else if( button == GLUT_RIGHT_BUTTON ) button = GLUT_LEFT_BUTTON;
+
+        /*
+         * Hey, what's up with you?
+         */
+        if( button == -1 )
+            return( DefWindowProc( hWnd, uMsg, lParam, wParam ) );
+
+        /*
+         * Do not execute the application's mouse callback if a menu is hooked to this button.
+         * In that case an appropriate private call should be generated.
+         * 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
+         */
+        if ( window->ActiveMenu != NULL )  /* Window has an active menu, it absorbs any mouse click */
+        {
+          if ( fgCheckActiveMenu ( window, window->ActiveMenu ) == TRUE )  /* Inside the menu, invoke the callback and deactivate the menu*/
+          {
+            /* Save the current window and menu and set the current window to the window whose menu this is */
+            SFG_Window *save_window = fgStructure.Window ;
+            SFG_Menu *save_menu = fgStructure.Menu ;
+            fgSetWindow ( window ) ;
+            fgStructure.Menu = window->ActiveMenu ;
+
+            /* Execute the menu callback */
+            fgExecuteMenuCallback ( window->ActiveMenu ) ;
+            fgDeactivateMenu ( window ) ;
+
+            /* Restore the current window and menu */
+            fgSetWindow ( save_window ) ;
+            fgStructure.Menu = save_menu ;
+          }
+          else  /* Outside the menu, deactivate the menu if it's a downclick */
+          {
+            if ( pressed == TRUE ) fgDeactivateMenu ( window ) ;
+          }
+
+          /*
+           * Let's make the window redraw as a result of the mouse click and menu activity.
+           */
+          window->State.Redisplay = TRUE ;
+
+          break ;
+        }
+
+        /*
+         * No active menu, let's check whether we need to activate one.
+         */
+        if ( ( window->Menu[ button ] != NULL ) && ( pressed == TRUE ) )
+        {
+            /*
+             * Let's make the window redraw as a result of the mouse click.
+             */
+            window->State.Redisplay = TRUE ;
+
+            /*
+             * Activate the appropriate menu structure...
+             */
+            fgActivateMenu( window, button );
+
+            break;
+        }
+
+        /*
+         * Check if there is a mouse callback hooked to the window
+         */
+        if( window->Callbacks.Mouse == NULL )
+            break;
+
+        /*
+         * Set the current window
+         */
+        fgSetWindow( window );
+
+        /*
+         * Remember the current modifiers state.
+         */
+        window->State.Modifiers = 
+            ( ( (GetKeyState( VK_LSHIFT   ) < 0 ) || ( GetKeyState( VK_RSHIFT   ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
+            ( ( (GetKeyState( VK_LCONTROL ) < 0 ) || ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL  : 0 ) |
+            ( ( (GetKeyState( VK_LMENU    ) < 0 ) || ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 0 );
+
+        /*
+         * Finally execute the mouse callback
+         */
+        window->Callbacks.Mouse(
+            button,
+            pressed == TRUE ? GLUT_DOWN : GLUT_UP,
+            window->State.MouseX,
+            window->State.MouseY
+        );
+
+        /*
+         * Trash the modifiers state
+         */
+        window->State.Modifiers = 0xffffffff;
+    }
+    break;
+
+    case WM_SYSKEYDOWN:
+    case WM_KEYDOWN:
+    {
+        int keypress = -1;
+        POINT mouse_pos ;
+
+        /*
+         * Ignore the automatic key repetition if needed:
+         */
+        if( fgState.IgnoreKeyRepeat && (lParam & KF_REPEAT) )
+            break;
+
+        /*
+         * Set the current window
+         */
+        fgSetWindow( window );
+
+        /*
+         * Remember the current modifiers state. This is done here in order 
+         * to make sure the VK_DELETE keyboard callback is executed properly.
+         */
+        window->State.Modifiers = 
+            ( ( (GetKeyState( VK_LSHIFT   ) < 0 ) || ( GetKeyState( VK_RSHIFT   ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
+            ( ( (GetKeyState( VK_LCONTROL ) < 0 ) || ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL  : 0 ) |
+            ( ( (GetKeyState( VK_LMENU    ) < 0 ) || ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 0 );
+
+        /*
+         * Set the mouse position
+         */
+        GetCursorPos ( &mouse_pos ) ;
+        ScreenToClient ( window->Window.Handle, &mouse_pos ) ;
+
+        window->State.MouseX = mouse_pos.x ;
+        window->State.MouseY = mouse_pos.y ;
+
+        /*
+         * Convert the Win32 keystroke codes to GLUTtish way
+         */
+#       define KEY(a,b) case a: keypress = b; break;
+
+        switch( wParam )
+        {
+            /*
+             * Most of the special characters can be handled automagically...
+             */
+            KEY( VK_F1,     GLUT_KEY_F1        ); KEY( VK_F2,     GLUT_KEY_F2        );
+            KEY( VK_F3,     GLUT_KEY_F3        ); KEY( VK_F4,     GLUT_KEY_F4        );
+            KEY( VK_F5,     GLUT_KEY_F5        ); KEY( VK_F6,     GLUT_KEY_F6        );
+            KEY( VK_F7,     GLUT_KEY_F7        ); KEY( VK_F8,     GLUT_KEY_F8        );
+            KEY( VK_F9,     GLUT_KEY_F9        ); KEY( VK_F10,    GLUT_KEY_F10       );
+            KEY( VK_F11,    GLUT_KEY_F11       ); KEY( VK_F12,    GLUT_KEY_F12       );
+            KEY( VK_PRIOR,  GLUT_KEY_PAGE_UP   ); KEY( VK_NEXT,   GLUT_KEY_PAGE_DOWN );
+            KEY( VK_HOME,   GLUT_KEY_HOME      ); KEY( VK_END,    GLUT_KEY_END       );
+            KEY( VK_LEFT,   GLUT_KEY_LEFT      ); KEY( VK_UP,     GLUT_KEY_UP        );
+            KEY( VK_RIGHT,  GLUT_KEY_RIGHT     ); KEY( VK_DOWN,   GLUT_KEY_DOWN      );
+            KEY( VK_INSERT, GLUT_KEY_INSERT    );
+
+            /*
+             * ...yet there is a small exception we need to have handled...
+             */
+            case VK_DELETE:
+                /*
+                 * The delete key should be treated as an ASCII keypress:
+                 */
+                if( window->Callbacks.Keyboard != NULL )
+                    window->Callbacks.Keyboard( 127, window->State.MouseX, window->State.MouseY );
+        }
+
+        /*
+         * Execute the special callback, if present, given the conversion was a success:
+         */
+        if( (keypress != -1) && (window->Callbacks.Special != NULL) )
+        {
+            /*
+             * Have the special callback executed:
+             */
+            window->Callbacks.Special( keypress, window->State.MouseX, window->State.MouseY );
+        }
+
+        /*
+         * Thrash the modifiers register now
+         */
+        window->State.Modifiers = 0xffffffff;
+    }
+    break;
+
+    case WM_SYSKEYUP:
+    case WM_KEYUP:
+    {
+        int keypress = -1;
+        POINT mouse_pos ;
+
+        /*
+         * Set the current window
+         */
+        fgSetWindow( window );
+
+        /*
+         * Remember the current modifiers state. This is done here in order 
+         * to make sure the VK_DELETE keyboard callback is executed properly.
+         */
+        window->State.Modifiers = 
+            ( ( (GetKeyState( VK_LSHIFT   ) < 0 ) || ( GetKeyState( VK_RSHIFT   ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
+            ( ( (GetKeyState( VK_LCONTROL ) < 0 ) || ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL  : 0 ) |
+            ( ( (GetKeyState( VK_LMENU    ) < 0 ) || ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 0 );
+
+        /*
+         * Set the mouse position
+         */
+        GetCursorPos ( &mouse_pos ) ;
+        ScreenToClient ( window->Window.Handle, &mouse_pos ) ;
+
+        window->State.MouseX = mouse_pos.x ;
+        window->State.MouseY = mouse_pos.y ;
+
+        /*
+         * Convert the Win32 keystroke codes to GLUTtish way.  "KEY(a,b)" was defined under "WM_KEYDOWN"
+         */
+
+        switch( wParam )
+        {
+          /*
+           * Most of the special characters can be handled automagically...
+           */
+          KEY( VK_F1,     GLUT_KEY_F1        ); KEY( VK_F2,     GLUT_KEY_F2        );
+          KEY( VK_F3,     GLUT_KEY_F3        ); KEY( VK_F4,     GLUT_KEY_F4        );
+          KEY( VK_F5,     GLUT_KEY_F5        ); KEY( VK_F6,     GLUT_KEY_F6        );
+          KEY( VK_F7,     GLUT_KEY_F7        ); KEY( VK_F8,     GLUT_KEY_F8        );
+          KEY( VK_F9,     GLUT_KEY_F9        ); KEY( VK_F10,    GLUT_KEY_F10       );
+          KEY( VK_F11,    GLUT_KEY_F11       ); KEY( VK_F12,    GLUT_KEY_F12       );
+          KEY( VK_PRIOR,  GLUT_KEY_PAGE_UP   ); KEY( VK_NEXT,   GLUT_KEY_PAGE_DOWN );
+          KEY( VK_HOME,   GLUT_KEY_HOME      ); KEY( VK_END,    GLUT_KEY_END       );
+          KEY( VK_LEFT,   GLUT_KEY_LEFT      ); KEY( VK_UP,     GLUT_KEY_UP        );
+          KEY( VK_RIGHT,  GLUT_KEY_RIGHT     ); KEY( VK_DOWN,   GLUT_KEY_DOWN      );
+          KEY( VK_INSERT, GLUT_KEY_INSERT    );
+
+          /*
+           * ...yet there is a small exception we need to have handled...
+           */
+          case VK_DELETE:
+            /*
+             * The delete key should be treated as an ASCII keypress:
+             */
+            if( window->Callbacks.KeyboardUp != NULL )
+                window->Callbacks.KeyboardUp( 127, window->State.MouseX, window->State.MouseY );
+
+            break ;
+          default:
+            {
+              /*
+               * Call the KeyboardUp callback for a regular character if there is one.
+               */
+              BYTE state[ 256 ];
+              WORD code[ 2 ];
+
+              GetKeyboardState(state);
+
+              if ( ToAscii( wParam, 0, state, code, 0 ) == 1 )
+                wParam=code[ 0 ];
+
+              if( window->Callbacks.KeyboardUp != NULL )
+                window->Callbacks.KeyboardUp( (char)wParam, window->State.MouseX, window->State.MouseY );
+            }
+        }
+
+        /*
+         * Execute the special callback, if present, given the conversion was a success:
+         */
+        if( (keypress != -1) && (window->Callbacks.SpecialUp != NULL) )
+        {
+            /*
+             * Have the special callback executed:
+             */
+            window->Callbacks.SpecialUp( keypress, window->State.MouseX, window->State.MouseY );
+        }
+
+        /*
+         * Thrash the modifiers register now
+         */
+        window->State.Modifiers = 0xffffffff;
+    }
+    break;
+
+    case WM_SYSCHAR:
+    case WM_CHAR:
+    {
+        /*
+         * Ignore the automatic key repetition if needed:
+         */
+        if( fgState.IgnoreKeyRepeat && (lParam & KF_REPEAT) )
+            break;
+
+        /*
+         * Clear to go with the keyboard callback, if registered:
+         */
+        if( window->Callbacks.Keyboard != NULL )
+        {
+            /*
+             * Remember the current modifiers state
+             */
+            window->State.Modifiers = 
+                ( ( (GetKeyState( VK_LSHIFT   ) < 0 ) || ( GetKeyState( VK_RSHIFT   ) < 0 )) ? GLUT_ACTIVE_SHIFT : 0 ) |
+                ( ( (GetKeyState( VK_LCONTROL ) < 0 ) || ( GetKeyState( VK_RCONTROL ) < 0 )) ? GLUT_ACTIVE_CTRL  : 0 ) |
+                ( ( (GetKeyState( VK_LMENU    ) < 0 ) || ( GetKeyState( VK_RMENU    ) < 0 )) ? GLUT_ACTIVE_ALT   : 0 );
+
+            /*
+             * Have the special callback executed:
+             */
+            window->Callbacks.Keyboard( (char)wParam, window->State.MouseX, window->State.MouseY );
+
+            /*
+             * Thrash the modifiers register now
+             */
+            window->State.Modifiers = 0xffffffff;
+        }
+    }
+    break;
+
+    case WM_CAPTURECHANGED :  /* User has finished resizing the window, force a redraw */
+      if ( window->Callbacks.Display )
+        window->Callbacks.Display () ;
+
+/*      lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ) ; */
+      break ;
+
+      /*
+       * Other messages that I have seen and which are not handled already
+       */
+    case WM_SETTEXT :  /* 0x000c */
+      lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );  /* Pass it on to "DefWindowProc" to set the window text */
+      break ;
+
+    case WM_GETTEXT :  /* 0x000d */
+      /* Ideally we would copy the title of the window into "lParam" */
+/*      strncpy ( (char *)lParam, "Window Title", wParam ) ;
+      lRet = ( wParam > 12 ) ? 12 : wParam ;  */ /* the number of characters copied */
+      lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
+      break ;
+
+    case WM_GETTEXTLENGTH :  /* 0x000e */
+      /* Ideally we would get the length of the title of the window */
+      lRet = 12 ;  /* the number of characters in "Window Title\0" (see above) */
+      break ;
+
+    case WM_ERASEBKGND :  /* 0x0014 */
+      lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
+      break ;
+
+    case WM_SYNCPAINT :  /* 0x0088 */
+      /* Another window has moved, need to update this one */
+      window->State.Redisplay = TRUE ;
+      lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );  /* Help screen says this message must be passed to "DefWindowProc" */
+      break ;
+
+    case WM_NCPAINT :  /* 0x0085 */
+      /* Need to update the border of this window */
+      lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );  /* Pass it on to "DefWindowProc" to repaint a standard border */
+      break ;
+
+    default:
+        /*
+         * Handle unhandled messages
+         */
+        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
+        break;
+    }
+
+    return( lRet );
+}
+#endif
+
+/*** END OF FILE ***/
diff --git a/src/freeglut_menu.c b/src/freeglut_menu.c
new file mode 100644 (file)
index 0000000..921deec
--- /dev/null
@@ -0,0 +1,860 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-menu"
+
+#include "../include/GL/freeglut.h"
+#include "freeglut_internal.h"
+
+/*
+ * TODO BEFORE THE STABLE RELEASE:
+ *
+ * It would be cool if the submenu entries were somehow marked, for example with a dings
+ * on the right menu border or something like that. Think about the possibility of doing
+ * the menu on layers *or* using the native window system instead of OpenGL.
+ */
+
+/* -- DEFINITIONS ---------------------------------------------------------- */
+
+/*
+ * We'll be using freeglut fonts to draw the menu
+ */
+#define  FREEGLUT_MENU_FONT    GLUT_BITMAP_8_BY_13
+#define  FREEGLUT_MENU_HEIGHT  15
+#define  FREEGLUT_MENU_BORDER   8
+
+
+/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
+
+/*
+ * Private static 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 = menu->Entries.First; entry; entry = entry->Node.Next)
+    {
+        if (i == index)
+            break;
+        ++i;
+    }
+
+    return entry;
+}
+
+/*
+ * Private static function to check for the current menu/sub menu activity state
+ */
+static GLboolean fghCheckMenuStatus( SFG_Window* window, SFG_Menu* menu )
+{
+  SFG_MenuEntry* menuEntry;
+  int x, y;
+
+  /*
+   * First of all check any of the active sub menus...
+   */
+  for( menuEntry = menu->Entries.First; menuEntry;
+       menuEntry = menuEntry->Node.Next )
+  {
+    /*
+     * Is that an active sub menu by any case?
+     */
+    if( menuEntry->SubMenu != NULL && menuEntry->IsActive == TRUE )
+    {
+      /*
+       * OK, have the sub-menu checked, too. If it returns 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...
+       */
+      if( fghCheckMenuStatus( window, menuEntry->SubMenu ) == TRUE )
+        return( TRUE );
+    }
+  }
+
+  /*
+   * That much about our sub menus, let's get to checking the current menu:
+   */
+  x = window->State.MouseX - menu->X;
+  y = window->State.MouseY - menu->Y;
+
+  /*
+   * Mark all menu entries inactive...
+   */
+  for( menuEntry = menu->Entries.First; menuEntry;
+       menuEntry = menuEntry->Node.Next )
+  {
+    menuEntry->IsActive = FALSE;
+  }
+
+  menu->IsActive = FALSE;
+
+  /*
+   * Check if the mouse cursor is contained within the current menu box
+   */
+  if( x >= 0 && x < menu->Width && y >= 0 && y < menu->Height )
+  {
+    /*
+     * Calculation of the highlighted menu item is easy enough now:
+     */
+    int menuID = y / FREEGLUT_MENU_HEIGHT;
+
+    /*
+     * The mouse cursor is somewhere over our box, check it out.
+     */
+    menuEntry = fghFindMenuEntry( menu, menuID + 1 );
+    assert( menuEntry != NULL );
+
+    /*
+     * Mark the menu as active...
+     */
+    menuEntry->IsActive = TRUE;
+    menuEntry->Ordinal = menuID;
+
+    /*
+     * Don't forget about marking the current menu as active, too:
+     */
+    menu->IsActive = TRUE;
+
+    /*
+     * 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 check function:
+     */
+    if( menuEntry->SubMenu != NULL )
+    {
+      /*
+       * Set up the initial menu position now...
+       */
+
+      menuEntry->SubMenu->X = menu->X + menu->Width ;
+      menuEntry->SubMenu->Y = menu->Y + menuEntry->Ordinal * FREEGLUT_MENU_HEIGHT ;
+
+      /*
+       * Make sure the submenu stays within the window
+       */
+      if ( menuEntry->SubMenu->X + menuEntry->SubMenu->Width > glutGet ( GLUT_WINDOW_WIDTH ) )
+      {
+        menuEntry->SubMenu->X = menu->X - menuEntry->SubMenu->Width ;
+        if ( menuEntry->SubMenu->X < 0 )
+          menuEntry->SubMenu->X = glutGet ( GLUT_WINDOW_WIDTH ) - menuEntry->SubMenu->Width ;
+      }
+
+      /*
+       * ...then check the submenu's state:
+       */
+      fghCheckMenuStatus( window, menuEntry->SubMenu );
+
+      /*
+       * Even if the submenu turned up inactive, activate it because its parent entry is active
+       */
+      menuEntry->SubMenu->IsActive = TRUE ;
+    }
+
+    /*
+     * Report back that we have caught the menu cursor
+     */
+    return( TRUE );
+  }
+
+  /*
+   * Looks like the menu cursor is somewhere else...
+   */
+  return( 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;
+
+  /*
+   * Have the menu box drawn first. The +- values are
+   * here just to make it more nice-looking...
+   */
+  glColor4f( 0.0f, 0.0f, 0.0f, 1.0f );
+  glBegin( GL_QUADS );
+    glVertex2i( menu->X              , menu->Y - 1                );
+    glVertex2i( menu->X + menu->Width, menu->Y - 1                );
+    glVertex2i( menu->X + menu->Width, menu->Y + 4 + menu->Height );
+    glVertex2i( menu->X              , menu->Y + 4 + menu->Height );
+  glEnd();
+
+  glColor4f( 0.3f, 0.4f, 0.5f, 1.0f );
+  glBegin( GL_QUADS );
+    glVertex2i( menu->X - 2              , menu->Y + 1                );
+    glVertex2i( menu->X - 2 + menu->Width, menu->Y + 1                );
+    glVertex2i( menu->X - 2 + menu->Width, menu->Y + 2 + menu->Height );
+    glVertex2i( menu->X - 2              , menu->Y + 2 + menu->Height );
+  glEnd();
+
+  /*
+   * Check if any of the submenus is currently active...
+   */
+  for( menuEntry = menu->Entries.First; menuEntry;
+       menuEntry = menuEntry->Node.Next )
+  {
+    /*
+     * Has the menu been marked as active, maybe?
+     */
+    if( menuEntry->IsActive == TRUE )
+    {
+      /*
+       * That's truly right, and we need to have it highlighted.
+       * There is an assumption that mouse cursor didn't move
+       * since the last check of menu activity state:
+       */
+      int menuID = menuEntry->Ordinal;
+
+      /*
+       * So have the highlight drawn...
+       */
+      glColor4f( 0.2f, 0.3f, 0.4f, 1.0f );
+      glBegin( GL_QUADS );
+        glVertex2i( menu->X - 2              , menu->Y + (menuID + 0)*FREEGLUT_MENU_HEIGHT + 1 );
+        glVertex2i( menu->X - 2 + menu->Width, menu->Y + (menuID + 0)*FREEGLUT_MENU_HEIGHT + 1 );
+        glVertex2i( menu->X - 2 + menu->Width, menu->Y + (menuID + 1)*FREEGLUT_MENU_HEIGHT + 2 );
+        glVertex2i( menu->X - 2              , menu->Y + (menuID + 1)*FREEGLUT_MENU_HEIGHT + 2 );
+      glEnd();
+    }
+  }
+
+  /*
+   * Print the menu entries now...
+   */
+  glColor4f( 1, 1, 1, 1 );
+
+  for( menuEntry = menu->Entries.First, i=0; menuEntry;
+       menuEntry = menuEntry->Node.Next, ++i )
+  {
+    /*
+     * Move the raster into position...
+     */
+    glRasterPos2i(
+        menu->X + FREEGLUT_MENU_BORDER,
+        menu->Y + (i + 1)*FREEGLUT_MENU_HEIGHT
+    );
+
+    /*
+     * Have the label drawn, character after character:
+     */
+    glutBitmapString( FREEGLUT_MENU_FONT, menuEntry->Text);
+
+    /*
+     * If it's a submenu, draw a right arrow
+     */
+    if ( menuEntry->SubMenu != NULL )
+    {
+      GLubyte arrow_char [] = { 0, 0, 32, 48, 56, 60, 62, 63, 62, 60, 56, 48, 32, 0, 0 } ;
+      int width = glutBitmapWidth ( FREEGLUT_MENU_FONT, ' ' ) ;
+
+      glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
+
+      /*
+       * Set up the pixel unpacking ways
+       */
+      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        );
+
+      glRasterPos2i ( menu->X + menu->Width - 2 - width,
+                      menu->Y + (i + 1)*FREEGLUT_MENU_HEIGHT ) ;
+      glBitmap ( width, FREEGLUT_MENU_HEIGHT, 0, 0, 0.0, 0.0, arrow_char ) ;
+      glPopClientAttrib();
+    }
+  }
+
+  /*
+   * Now we are ready to check if any of our children needs to be redrawn:
+   */
+  for( menuEntry = menu->Entries.First; menuEntry;
+       menuEntry = menuEntry->Node.Next )
+  {
+    /*
+     * Is that an active sub menu by any case?
+     */
+    if( menuEntry->SubMenu != NULL && menuEntry->IsActive == TRUE )
+    {
+      /*
+       * Yeah, indeed. Have it redrawn now:
+       */
+      fghDisplayMenuBox( menuEntry->SubMenu );
+    }
+  }
+}
+
+/*
+ * Displays the currently active menu for the current window
+ */
+void fgDisplayMenu( void )
+{
+    SFG_Window* window = fgStructure.Window;
+    SFG_Menu* menu = NULL;
+
+    /*
+     * Make sure there is a current window available
+     */
+    freeglut_assert_window;
+
+    /*
+     * Check if there is an active menu attached to this window...
+     */
+    menu = window->ActiveMenu;
+
+    /*
+     * Did we find an active window?
+     */
+    freeglut_return_if_fail( menu != NULL );
+    /*
+     * Prepare the OpenGL state to do the rendering first:
+     */
+    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  );
+
+    /*
+     * We'll use an orthogonal projection matrix to draw the menu:
+     */
+    glMatrixMode( GL_PROJECTION );
+    glPushMatrix();
+    glLoadIdentity();
+    glOrtho(
+         0, glutGet( GLUT_WINDOW_WIDTH  ),
+         glutGet( GLUT_WINDOW_HEIGHT ), 0,
+        -1, 1
+    );
+
+    /*
+     * Model-view matix gets reset to identity:
+     */
+    glMatrixMode( GL_MODELVIEW );
+    glPushMatrix();
+    glLoadIdentity();
+
+    /*
+     * First of all, have the exact menu status check:
+     */
+    fghCheckMenuStatus( window, menu );
+
+    /*
+     * The status has been updated and we're ready to have the menu drawn now:
+     */
+    fghDisplayMenuBox( menu );
+
+    /*
+     * Restore the old OpenGL settings now
+     */
+    glPopAttrib();
+
+    glMatrixMode( GL_PROJECTION );
+    glPopMatrix();
+    glMatrixMode( GL_MODELVIEW );
+    glPopMatrix();
+}
+
+/*
+ * Activates a menu pointed by the function argument
+ */
+void fgActivateMenu( SFG_Window* window, int button )
+{
+  int x, y;
+
+  /*
+   * We'll be referencing this menu a lot, so remember its address:
+   */
+  SFG_Menu* menu = window->Menu[ button ];
+
+  /*
+   * Mark the menu as active, so that it gets displayed:
+   */
+  window->ActiveMenu = menu;
+  menu->IsActive = TRUE ;
+
+  /*
+   * Grab the mouse cursor position respective to the current window
+   */
+  x = window->State.MouseX;
+  y = window->State.MouseY;
+
+  /*
+   * Set up the initial menu position now:
+   */
+  menu->X = x ;
+  menu->Y = y ;
+
+  fgSetWindow ( window ) ;
+
+  if( x > ( glutGet( GLUT_WINDOW_WIDTH ) - menu->Width ) )
+    menu->X = glutGet( GLUT_WINDOW_WIDTH ) - menu->Width;
+  if( y > ( glutGet( GLUT_WINDOW_HEIGHT ) - menu->Height) )
+    menu->Y = glutGet( GLUT_WINDOW_HEIGHT ) - menu->Height;
+}
+
+/*
+ * Check whether an active menu absorbs a mouse click
+ */
+GLboolean fgCheckActiveMenu ( SFG_Window *window, SFG_Menu *menu )
+{
+  /*
+   * Near as I can tell, this is the active menu behaviour:
+   *  - 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 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 check this recursively.
+   */
+  return fghCheckMenuStatus ( window, menu ) ;
+}
+
+/*
+ * Function to check for menu entry selection on menu deactivation
+ */
+void fgExecuteMenuCallback( SFG_Menu* menu )
+{
+  SFG_MenuEntry *menuEntry;
+
+  /*
+   * First of all check any of the active sub menus...
+   */
+  for( menuEntry = menu->Entries.First; menuEntry; menuEntry = menuEntry->Node.Next)
+  {
+    /*
+     * Is this menu entry active?
+     */
+    if( menuEntry->IsActive == TRUE )
+    {
+      /*
+       * If there is not a sub menu, execute the menu callback and return...
+       */
+      if( menuEntry->SubMenu == NULL )
+      {
+        /*
+         * ...certainly given that there is one...
+         */
+        if( menu->Callback != NULL )
+          menu->Callback( menuEntry->ID );
+
+        return;
+      }
+
+      /*
+       * Otherwise recurse into the submenu.
+       */
+      fgExecuteMenuCallback( menuEntry->SubMenu );
+
+      /*
+       * There is little sense in dwelling the search on
+       */
+      return;
+    }
+  }
+}
+
+/*
+ * Deactivates a menu pointed by the function argument.
+ */
+void fgDeactivateMenu( SFG_Window *window )
+{
+    /*
+     * Check if there is an active menu attached to this window...
+     */
+    SFG_Menu* menu = window->ActiveMenu;
+
+    /*
+     * Did we find an active window?
+     */
+    freeglut_return_if_fail( menu != NULL );
+
+    /*
+     * Forget about having that menu active anymore, now:
+     */
+    window->ActiveMenu = NULL;
+    menu->IsActive = FALSE ;
+}
+
+/*
+ * 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_assert_ready; freeglut_return_if_fail( fgStructure.Menu != NULL );
+
+  /*
+   * The menu's box size depends on the menu entries:
+   */
+  for( menuEntry = fgStructure.Menu->Entries.First; menuEntry;
+       menuEntry = menuEntry->Node.Next)
+  {
+    /*
+     * Update the menu entry's width value
+     */
+    menuEntry->Width = glutBitmapLength( FREEGLUT_MENU_FONT, menuEntry->Text );
+
+    /*
+     * 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.Menu->Height = height; 
+  fgStructure.Menu->Width  = width + 2 * 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
+     */
+    return( fgCreateMenu( callback )->ID );
+}
+
+/*
+ * Destroys a menu object, removing all references to it
+ */
+void FGAPIENTRY glutDestroyMenu( int menuID )
+{
+    SFG_Menu* menu = fgMenuByID( menuID );
+
+    freeglut_assert_ready; freeglut_return_if_fail( menu != NULL );
+
+    /*
+     * 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_assert_ready;
+
+    /*
+     * Is there a current menu set?
+     */
+    if( fgStructure.Menu != NULL )
+    {
+        /*
+         * Yes, there is indeed...
+         */
+        return( fgStructure.Menu->ID );
+    }
+
+    /*
+     * No, there is no current menu at all
+     */
+    return( 0 );
+}
+
+/*
+ * Sets the current menu given its menu ID
+ */
+void FGAPIENTRY glutSetMenu( int menuID )
+{
+    SFG_Menu* menu = fgMenuByID( menuID );
+
+    freeglut_assert_ready; freeglut_return_if_fail( menu != NULL );
+
+    /*
+     * The current menu pointer is stored in fgStructure.Menu
+     */
+    fgStructure.Menu = menu;
+}
+
+/*
+ * Adds a menu entry to the bottom of the current menu
+ */
+void FGAPIENTRY glutAddMenuEntry( const char* label, int value )
+{
+    SFG_MenuEntry* menuEntry = calloc( sizeof(SFG_MenuEntry), 1 );
+
+    /*
+     * Make sure there is a current menu set
+     */
+    freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Menu != NULL );
+
+    /*
+     * Fill in the appropriate values...
+     */
+    menuEntry->Text = strdup( label );
+    menuEntry->ID   = value;
+
+    /*
+     * Have the new menu entry attached to the current menu
+     */
+    fgListAppend( &fgStructure.Menu->Entries, &menuEntry->Node );
+
+    /*
+     * Update the menu's dimensions now
+     */
+    fghCalculateMenuBoxSize();
+}
+
+/*
+ * Add a sub menu to the bottom of the current menu
+ */
+void FGAPIENTRY glutAddSubMenu( const char* label, int subMenuID )
+{
+  SFG_MenuEntry* menuEntry = calloc( sizeof(SFG_MenuEntry), 1 );
+  SFG_Menu*      subMenu = fgMenuByID( subMenuID );
+
+  /*
+   * Make sure there is a current menu and the sub menu
+   * we want to attach actually exists...
+   */
+  freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Menu != NULL );
+  freeglut_return_if_fail( subMenu != NULL );
+
+  /*
+   * Fill in the appropriate values
+   */
+  menuEntry->Text = strdup( label );
+  menuEntry->SubMenu = subMenu;
+  menuEntry->ID      = -1;
+
+  /*
+   * Have the new menu entry attached to the current menu
+   */
+  fgListAppend( &fgStructure.Menu->Entries, &menuEntry->Node );
+
+  /*
+   * Update the menu's dimensions now
+   */
+  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;
+
+    /*
+     * Make sure there is a current menu set...
+     */
+    freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Menu != NULL );
+
+    /*
+     * Get n-th menu entry in the current menu, starting from one:
+     */
+    menuEntry = fghFindMenuEntry( fgStructure.Menu, item );
+
+    /*
+     * Make sure the menu entry exists
+     */
+    freeglut_return_if_fail( menuEntry != NULL );
+
+    /*
+     * We want it to become a normal menu entry, so:
+     */
+    if( menuEntry->Text != NULL )
+        free( menuEntry->Text );
+
+    menuEntry->Text = strdup( label );
+    menuEntry->ID      = value;
+    menuEntry->SubMenu = NULL;
+
+    /*
+     * Update the menu's dimensions now
+     */
+    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 = fgMenuByID( subMenuID );
+    SFG_MenuEntry* menuEntry = NULL;
+
+    /*
+     * Make sure there is a current menu set and the sub menu exists...
+     */
+    freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Menu != NULL );
+    freeglut_return_if_fail( subMenu != NULL );
+
+    /*
+     * Get n-th menu entry in the current menu, starting from one:
+     */
+    menuEntry = fghFindMenuEntry( fgStructure.Menu, item );
+
+    /*
+     * Make sure the menu entry exists
+     */
+    freeglut_return_if_fail( menuEntry != NULL );
+
+    /*
+     * We want it to become a sub menu entry, so:
+     */
+    if( menuEntry->Text != NULL )
+        free( menuEntry->Text );
+
+    menuEntry->Text = strdup( label );
+    menuEntry->SubMenu = subMenu;
+    menuEntry->ID      = -1;
+
+    /*
+     * Update the menu's dimensions now
+     */
+    fghCalculateMenuBoxSize();
+}
+
+/*
+ * Removes the specified menu item from the current menu
+ */
+void FGAPIENTRY glutRemoveMenuItem( int item )
+{
+    SFG_MenuEntry* menuEntry;
+
+    /*
+     * Make sure there is a current menu set
+     */
+    freeglut_assert_ready; freeglut_return_if_fail( fgStructure.Menu != NULL );
+
+    /*
+     * Get n-th menu entry in the current menu, starting from one:
+     */
+    menuEntry = fghFindMenuEntry( fgStructure.Menu, item );
+
+    /*
+     * Make sure the menu entry exists
+     */
+    freeglut_return_if_fail( menuEntry != NULL );
+
+    /*
+     * Removing a menu entry is quite simple...
+     */
+    fgListRemove( &fgStructure.Menu->Entries, &menuEntry->Node );
+
+    /*
+     * Free the entry label string, too
+     */
+    free( menuEntry->Text );
+
+    free( menuEntry );
+
+    /*
+     * Update the menu's dimensions now
+     */
+    fghCalculateMenuBoxSize();
+}
+
+/*
+ * Attaches a menu to the current window
+ */
+void FGAPIENTRY glutAttachMenu( int button )
+{
+    freeglut_assert_ready;
+
+    /*
+     * There must be a current window and a current menu set:
+     */
+    freeglut_return_if_fail( fgStructure.Window != NULL || fgStructure.Menu != NULL );
+
+    /*
+     * Make sure the button value is valid (0, 1 or 2, see freeglut.h)
+     */
+    freeglut_return_if_fail( button == GLUT_LEFT_BUTTON || button == GLUT_MIDDLE_BUTTON || button == GLUT_RIGHT_BUTTON );
+
+    /*
+     * It is safe now to attach the menu
+     */
+    fgStructure.Window->Menu[ button ] = fgStructure.Menu;
+}
+
+/*
+ * Detaches a menu from the current window
+ */
+void FGAPIENTRY glutDetachMenu( int button )
+{
+    freeglut_assert_ready;
+
+    /*
+     * There must be a current window set:
+     */
+    freeglut_return_if_fail( fgStructure.Window != NULL );
+
+    /*
+     * Make sure the button value is valid (0, 1 or 2, see freeglut.h)
+     */
+    freeglut_return_if_fail( button != 0 && button != 1 && button != 2 );
+
+    /*
+     * It is safe now to detach the menu
+     */
+    fgStructure.Window->Menu[ button ] = NULL;
+}
+
+/*
+ * A.Donev: Set and retrieve the menu's user data
+ */
+void* FGAPIENTRY glutGetMenuData( void )
+{
+   return(fgStructure.Menu->UserData);
+}
+
+void FGAPIENTRY glutSetMenuData(void* data)
+{
+  fgStructure.Menu->UserData=data;
+}
+
+/*** END OF FILE ***/
diff --git a/src/freeglut_misc.c b/src/freeglut_misc.c
new file mode 100644 (file)
index 0000000..496ca45
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-misc"
+
+#include "../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
+ */
+int FGAPIENTRY glutExtensionSupported( const char* extension )
+{
+  const char *extensions;
+  const char *ptr;
+  int len = strlen ( extension ) ;
+
+  /*
+   * Make sure there is a current window, and thus -- a current context available
+   */
+  freeglut_assert_ready;
+  freeglut_return_val_if_fail( fgStructure.Window != NULL, 0 );
+
+  /*
+   * Note it is safe to query the extensions
+   */
+  extensions = glGetString(GL_EXTENSIONS);
+
+  freeglut_return_val_if_fail( extensions != NULL, 0 );
+
+  /*
+   * Check if the extension itself looks valid
+   */
+  if ( strchr ( extension, ' ' ) != NULL )
+    return( 0 );
+
+  /*
+   * Look for our extension
+   */
+  for (ptr = extensions; *ptr;)
+  {
+    /*
+     * Is it the current extension?
+     */
+    if ( strncmp ( extension, extensions, len ) == 0 )
+      return 1 ;
+
+    /*
+     * No, go find the next extension.  They are separated from each other by one or more blank spaces.
+     */
+    ptr = strchr ( ptr + len, ' ' ) ;
+
+    /*
+     * If we ran off the end of the "extensions" character string, we didn't find it.  Return failure.
+     */
+    if ( !ptr ) return 0 ;
+
+    while ( *ptr == ' ' )
+      ptr++ ;
+  }
+
+  return 0 ;
+}
+
+/*
+ * This function reports all the OpenGL errors that happened till now
+ */
+void FGAPIENTRY glutReportErrors( void )
+{
+    GLenum error = glGetError();
+
+    /*
+     * Keep reporting errors as long as there are any...
+     */
+    while( error != GL_NO_ERROR )
+    {
+        /*
+         * Print the current error
+         */
+#       undef  G_LOG_DOMAIN
+#       define G_LOG_DOMAIN ((gchar *) 0)
+
+        fgWarning( "GL error: %s", gluErrorString( error ) );
+
+#       undef   G_LOG_DOMAIN
+#       define  G_LOG_DOMAIN  "freeglut_misc.c"
+
+        /*
+         * Grab the next error value
+         */
+        error = glGetError();
+    };
+}
+
+/*
+ * Turns the ignore key auto repeat feature on and off
+ */
+void FGAPIENTRY glutIgnoreKeyRepeat( int ignore )  /* DEPRECATED 11/4/02 - Do not use */
+{
+    /*
+     * This is simple and not damaging...
+     */
+    fgState.IgnoreKeyRepeat = ignore ? TRUE : FALSE;
+}
+
+/*
+ * Hints the window system whether to generate key auto repeat, or not. This is evil.
+ */
+void FGAPIENTRY glutSetKeyRepeat( int repeatMode )
+{
+#if TARGET_HOST_UNIX_X11
+
+    freeglut_assert_ready;
+
+    /*
+     * This is really evil, but let's have this done.
+     */
+    switch( repeatMode )
+    {
+    case GLUT_KEY_REPEAT_OFF:   XAutoRepeatOff( fgDisplay.Display ); break;
+    case GLUT_KEY_REPEAT_ON:    XAutoRepeatOn( fgDisplay.Display );  break;
+    case GLUT_KEY_REPEAT_DEFAULT:
+        {
+            XKeyboardState keyboardState;
+
+            /*
+             * Query the current keyboard state
+             */
+            XGetKeyboardControl( fgDisplay.Display, &keyboardState );
+
+            /*
+             * Set the auto key repeat basing on the global settings
+             */
+            glutSetKeyRepeat(
+                keyboardState.global_auto_repeat == AutoRepeatModeOn ?
+                GLUT_KEY_REPEAT_ON : GLUT_KEY_REPEAT_OFF
+            );
+        }
+        break;
+
+    default:
+        /*
+         * Whoops, this was not expected at all
+         */
+        break;
+    }
+
+#endif
+}
+
+/*
+ * Forces the joystick callback to be executed
+ */
+void FGAPIENTRY glutForceJoystickFunc( void )
+{
+    freeglut_assert_ready;
+
+    /*
+     * Is there a current window selected?
+     */
+    freeglut_return_if_fail( fgStructure.Window != NULL );
+
+    /*
+     * Check if there is a joystick callback hooked to the current window
+     */
+    freeglut_return_if_fail( fgStructure.Window->Callbacks.Joystick != NULL );
+
+    /*
+     * Poll the joystick now, using the current window's joystick callback
+     */
+    fgJoystickPollWindow( fgStructure.Window );
+}
+
+/*
+ *
+ */
+void FGAPIENTRY glutSetColor( int nColor, GLfloat red, GLfloat green, GLfloat blue )
+{
+    /*
+     *
+     */
+}
+
+/*
+ *
+ */
+GLfloat FGAPIENTRY glutGetColor( int color, int component )
+{
+    /*
+     *
+     */
+    return( 0.0f );
+}
+
+/*
+ *
+ */
+void FGAPIENTRY glutCopyColormap( int window )
+{
+    /*
+     *
+     */
+}
+
+/*** END OF FILE ***/
diff --git a/src/freeglut_overlay.c b/src/freeglut_overlay.c
new file mode 100644 (file)
index 0000000..14c42c2
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-overlay"
+
+#include "../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 ***/
diff --git a/src/freeglut_state.c b/src/freeglut_state.c
new file mode 100644 (file)
index 0000000..cb40f05
--- /dev/null
@@ -0,0 +1,704 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-state"
+
+#include "../include/GL/freeglut.h"
+#include "freeglut_internal.h"
+
+/*
+ * TODO BEFORE THE STABLE RELEASE:
+ *
+ *  glutGet()               -- X11 tests passed, but check if all enums handled (what about Win32?)
+ *  glutDeviceGet()         -- X11 tests passed, but check 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 ;
+
+  /*
+   * Return nothing if there is no current window set
+   */
+  if( fgStructure.Window == NULL )
+    return( 0 );
+
+  /*
+   * glXGetConfig should work fine
+   */
+  glXGetConfig( fgDisplay.Display, fgStructure.Window->Window.VisualInfo, attribute, &returnValue );
+
+
+  /*
+   * Have the query results returned
+   */
+  return ( returnValue ) ;
+}
+#endif
+
+/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
+
+/*
+ * General settings assignment method
+ */
+void FGAPIENTRY glutSetOption( GLenum eWhat, int value )
+{
+  freeglut_assert_ready;
+
+  /*
+   * Check what is the caller querying for. In chronological code add 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_WINDOW_CURSOR:
+      if( fgStructure.Window != NULL ) fgStructure.Window->State.Cursor = value ;
+      break ;
+
+  default:
+      /*
+       * Just have it reported, so that we can see what needs to be implemented
+       */
+      fgWarning( "glutSetOption(): missing enum handle %i\n", eWhat );
+      break;
+  }
+}
+
+/*
+ * General settings query method
+ */
+int FGAPIENTRY glutGet( GLenum eWhat )
+{
+    int returnValue ;
+    GLboolean boolValue ;
+
+    if ( eWhat == GLUT_INIT_STATE )
+       return ( fgState.Time.Set ) ;
+
+    freeglut_assert_ready;
+
+    /*
+     * Check what is the caller querying for. In chronological code add order.
+     */
+    switch( eWhat )
+    {
+    case GLUT_ELAPSED_TIME:
+        /*
+         * This is easy and nicely portable, as we are using GLib...
+         */
+        return( fgElapsedTime() );
+
+    /*
+     * 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:
+        /*
+         * 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 check 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:
+        /*
+         * Check for the visual type
+         */
+        if( (fghGetConfig( GLX_RGBA )) || (fgStructure.Window == 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 );
+        }
+
+        /*
+         * Otherwise return the number of entries in the colormap
+         */
+        return( fgStructure.Window->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_WIDTH:
+    case GLUT_WINDOW_HEIGHT:
+    case GLUT_WINDOW_BORDER_WIDTH :
+    case GLUT_WINDOW_HEADER_HEIGHT :
+    {
+        XWindowAttributes winAttributes;
+
+        /*
+         * Return zero if there is no current window set
+         */
+        if( fgStructure.Window == NULL )
+            return( 0 );
+
+        /*
+         * Grab the current window's attributes now
+         */
+        XGetWindowAttributes(
+            fgDisplay.Display,
+            fgStructure.Window->Window.Handle,
+            &winAttributes
+        );
+
+        /*
+         * See which window attribute to return
+         */
+        switch ( eWhat )
+        {
+        case GLUT_WINDOW_X:                return winAttributes.x ;
+        case GLUT_WINDOW_Y:                return winAttributes.y ;
+        case GLUT_WINDOW_WIDTH:            return winAttributes.width ;
+        case GLUT_WINDOW_HEIGHT:           return winAttributes.height ;
+        case GLUT_WINDOW_BORDER_WIDTH :    return winAttributes.border_width ;
+        case GLUT_WINDOW_HEADER_HEIGHT :   return winAttributes.border_width * 3 ;  /* a kludge for now */
+        }
+    }
+
+    /*
+     * I do not know yet if there will be a fgChooseVisual() function for Win32
+     */
+    case GLUT_DISPLAY_MODE_POSSIBLE:
+        /*
+         * Check if the current display mode is possible
+         */
+        return( fgChooseVisual() == NULL ? 0 : 1 );
+
+    /*
+     * This is system-dependant
+     */
+    case GLUT_WINDOW_FORMAT_ID:
+        /*
+         * Return the visual ID, if there is a current window naturally:
+         */
+        if( fgStructure.Window == NULL )
+            return( 0 );
+
+        return( fgStructure.Window->Window.VisualInfo->visualid );
+
+#elif TARGET_HOST_WIN32
+
+    /*
+     * Handle the OpenGL inquiries
+     */
+    case GLUT_WINDOW_RGBA:
+      glGetBooleanv ( GL_RGBA_MODE, &boolValue ) ;         /* True if color buffers store RGBA */
+      returnValue = boolValue ? 1 : 0 ;
+      return ( returnValue ) ;
+    case GLUT_WINDOW_DOUBLEBUFFER:
+      glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue ) ;      /* True if front and back buffers exist */
+      returnValue = boolValue ? 1 : 0 ;
+      return ( returnValue ) ;
+    case GLUT_WINDOW_STEREO:
+      glGetBooleanv ( GL_STEREO, &boolValue ) ;            /* True if left and right buffers exist */
+      returnValue = boolValue ? 1 : 0 ;
+      return ( returnValue ) ;
+
+    case GLUT_WINDOW_RED_SIZE:
+      glGetIntegerv ( GL_RED_BITS, &returnValue ) ;          /* Number of bits per red component in color buffers */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_GREEN_SIZE:
+      glGetIntegerv ( GL_GREEN_BITS, &returnValue ) ;        /* Number of bits per green component in color buffers */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_BLUE_SIZE:
+      glGetIntegerv ( GL_BLUE_BITS, &returnValue ) ;         /* Number of bits per blue component in color buffers */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_ALPHA_SIZE:
+      glGetIntegerv ( GL_ALPHA_BITS, &returnValue ) ;        /* Number of bits per alpha component in color buffers */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_ACCUM_RED_SIZE:
+      glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue ) ;    /* Number of bits per red component in the accumulation buffer */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_ACCUM_GREEN_SIZE:
+      glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue ) ;  /* Number of bits per green component in the accumulation buffer */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_ACCUM_BLUE_SIZE:
+      glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue ) ;   /* Number of bits per blue component in the accumulation buffer */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_ACCUM_ALPHA_SIZE:
+      glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue ) ;  /* Number of bits per alpha component in the accumulation buffer */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_DEPTH_SIZE:
+      glGetIntegerv ( GL_DEPTH_BITS, &returnValue ) ;        /* Number of depth-buffer bitplanes */
+      return ( returnValue ) ;
+
+    case GLUT_WINDOW_BUFFER_SIZE:
+      returnValue = 1 ;                                      /* ????? */
+      return ( returnValue ) ;
+    case GLUT_WINDOW_STENCIL_SIZE:
+      returnValue = 0 ;                                      /* ????? */
+      return ( returnValue ) ;
+
+    /*
+     * Window position and size
+     */
+    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 Linux; since
+         * platform independence is a virtue for "freeglut", we decided to break with GLUT's
+         * behaviour.
+         *  Under Linux, 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 Linux:
+         *  - 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;
+
+        /*
+         * Check if there is a window to be queried for dimensions:
+         */
+        freeglut_return_val_if_fail( fgStructure.Window != NULL, 0 );
+
+        /*
+         * We need to call GetWindowRect() first...
+         *  (this returns the pixel coordinates of the outside of the window)
+         */
+        GetWindowRect( fgStructure.Window->Window.Handle, &winRect );
+
+        /*
+         * ...then we've got to correct the results we've just received...
+         */
+        if (fgStructure.GameMode != fgStructure.Window &&
+           fgStructure.Window->Parent == NULL )
+        {
+          winRect.left   += GetSystemMetrics( SM_CXSIZEFRAME );
+          winRect.right  -= GetSystemMetrics( SM_CXSIZEFRAME );
+          winRect.top    += GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION );
+          winRect.bottom -= GetSystemMetrics( SM_CYSIZEFRAME );
+        }
+
+        /*
+         * ...and finally return the caller the desired value:
+         */
+        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 :
+        return ( GetSystemMetrics( SM_CXSIZEFRAME ) ) ;
+
+    case GLUT_WINDOW_HEADER_HEIGHT :
+        return ( GetSystemMetrics( SM_CYCAPTION ) ) ;
+
+    case GLUT_DISPLAY_MODE_POSSIBLE:
+        /*
+         * Check if the current display mode is possible
+         */
+        return( fgSetupPixelFormat( fgStructure.Window, TRUE, PFD_MAIN_PLANE ) );
+
+    case GLUT_WINDOW_FORMAT_ID:
+        /*
+         * Return the pixel format of the current window
+         */
+        if( fgStructure.Window != NULL )
+            return( GetPixelFormat( fgStructure.Window->Window.Device ) );
+
+        /*
+         * If the current window does not exist, fail:
+         */
+        return( 0 );
+
+#endif
+
+    /*
+     * The window structure queries
+     */
+    case GLUT_WINDOW_PARENT:
+        /*
+         * Return the ID number of current window's parent, if any
+         */
+        if( fgStructure.Window         == NULL ) return( 0 );
+        if( fgStructure.Window->Parent == NULL ) return( 0 );
+
+        return( fgStructure.Window->Parent->ID );
+
+    case GLUT_WINDOW_NUM_CHILDREN:
+        /*
+         * Return the number of children attached to the current window
+         */
+        if( fgStructure.Window == NULL )
+            return( 0 );
+
+        return( fgListLength( &fgStructure.Window->Children ) );
+
+    case GLUT_WINDOW_CURSOR:
+        /*
+         * Return the currently selected window cursor
+         */
+        if( fgStructure.Window == NULL )
+            return( 0 );
+
+        return( fgStructure.Window->State.Cursor );
+
+    case GLUT_MENU_NUM_ITEMS:
+        /*
+         * Return the number of menu entries in the current menu
+         */
+        if( fgStructure.Menu == NULL )
+            return( 0 );
+
+        return( fgListLength( &fgStructure.Menu->Entries ) );
+
+    case GLUT_ACTION_ON_WINDOW_CLOSE:
+       return fgState.ActionOnWindowClose;
+
+    case GLUT_VERSION:
+       return VERSION_MAJOR * 10000 + VERSION_MINOR * 100 + VERSION_PATCH;
+
+    default:
+        /*
+         * Just have it reported, so that we can see what needs to be implemented
+         */
+        fgWarning( "glutGet(): missing enum handle %i\n", eWhat );
+        break;
+    }
+
+    /*
+     * If nothing happens, then we are in deep trouble...
+     */
+    return( -1 );
+}
+
+/*
+ * Returns various device information.
+ */
+int FGAPIENTRY glutDeviceGet( GLenum eWhat )
+{
+    freeglut_assert_ready;
+
+    /*
+     * See why are we bothered...
+     *
+     * WARNING: we are mostly lying in this function.
+     */
+    switch( eWhat )
+    {
+    case GLUT_HAS_KEYBOARD:
+        /*
+         * We always have a keyboard present on PC machines...
+         */
+        return( TRUE );
+
+#if TARGET_HOST_UNIX_X11
+
+    case GLUT_HAS_MOUSE:
+        /*
+         * Hey, my Atari 65XE hasn't had a mouse!
+         */
+        return( TRUE );
+
+    case GLUT_NUM_MOUSE_BUTTONS:
+        /*
+         * Return the number of mouse buttons available. This is a big guess.
+         */
+        return( 3 );
+
+#elif TARGET_HOST_WIN32
+
+    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...
+         */
+        return( GetSystemMetrics( SM_CMOUSEBUTTONS ) );
+
+#endif
+
+    case GLUT_JOYSTICK_POLL_RATE:
+    case GLUT_HAS_JOYSTICK:
+    case GLUT_JOYSTICK_BUTTONS:
+    case GLUT_JOYSTICK_AXES:
+        /*
+         * WARNING: THIS IS A BIG LIE!
+         */
+        return( 0 );
+
+    case GLUT_HAS_SPACEBALL:
+    case GLUT_HAS_DIAL_AND_BUTTON_BOX:
+    case GLUT_HAS_TABLET:
+        /*
+         * Sounds cool. And unuseful.
+         */
+        return( FALSE );
+
+    case GLUT_NUM_SPACEBALL_BUTTONS:
+    case GLUT_NUM_BUTTON_BOX_BUTTONS:
+    case GLUT_NUM_DIALS:
+    case GLUT_NUM_TABLET_BUTTONS:
+        /*
+         * Zero is not the answer. Zero is the question. Continuum is the answer.
+         */
+        return( 0 );
+
+    case GLUT_DEVICE_IGNORE_KEY_REPEAT:
+        /*
+         * Return what we think about the key auto repeat settings
+         */
+        return( fgState.IgnoreKeyRepeat );
+
+    case GLUT_DEVICE_KEY_REPEAT:
+        /*
+         * WARNING: THIS IS A BIG LIE!
+         */
+        return( GLUT_KEY_REPEAT_DEFAULT );
+
+    default:
+        /*
+         * Complain.
+         */
+        fgWarning( "glutDeviceGet(): missing enum handle %i\n", eWhat );
+        break;
+    }
+
+    /*
+     * And now -- the failure.
+     */
+    return( -1 );
+}
+
+/*
+ * This should return the current state of ALT, SHIFT and CTRL keys.
+ */
+int FGAPIENTRY glutGetModifiers( void )
+{
+    /*
+     * Fail if there is no current window or called outside an input callback
+     */
+    if( fgStructure.Window == NULL )
+        return( 0 );
+
+    if( fgStructure.Window->State.Modifiers == 0xffffffff )
+    {
+        fgWarning( "glutGetModifiers() called outside an input callback" );
+        return( 0 );
+    }
+
+    /*
+     * Return the current modifiers state otherwise
+     */
+    return( fgStructure.Window->State.Modifiers );
+}
+
+/*
+ * Return the state of the GLUT API overlay subsystem. A misery ;-)
+ */
+int FGAPIENTRY glutLayerGet( GLenum eWhat )
+{
+    freeglut_assert_ready;
+
+    /*
+     * This is easy as layers are not implemented ;-)
+     */
+    switch( eWhat )
+    {
+
+#if TARGET_HOST_UNIX_X11
+
+    case GLUT_OVERLAY_POSSIBLE:
+        /*
+         * Nope, overlays are not possible.
+         */
+        return( FALSE );
+
+    case GLUT_LAYER_IN_USE:
+        /*
+         * The normal plane is always in use
+         */
+        return( GLUT_NORMAL );
+
+    case GLUT_HAS_OVERLAY:
+        /*
+         * No window is allowed to have an overlay
+         */
+        return( FALSE );
+
+    case GLUT_TRANSPARENT_INDEX:
+        /*
+         * Return just anything, which is always defined as zero
+         */
+        return( 0 );
+
+    case GLUT_NORMAL_DAMAGED:
+        /*
+         * Actually I do not know. Maybe.
+         */
+        return( FALSE );
+
+    case GLUT_OVERLAY_DAMAGED:
+        /*
+         * Return minus one to mark that no layer is in use
+         */
+        return( -1 );
+
+#elif TARGET_HOST_WIN32
+
+    case GLUT_OVERLAY_POSSIBLE:
+        /*
+         * Check if an overlay display mode is possible
+         */
+        return( fgSetupPixelFormat( fgStructure.Window, TRUE, PFD_OVERLAY_PLANE ) );
+
+    case GLUT_LAYER_IN_USE:
+        /*
+         * The normal plane is always in use
+         */
+        return( GLUT_NORMAL );
+
+    case GLUT_HAS_OVERLAY:
+        /*
+         * No window is allowed to have an overlay
+         */
+        return( FALSE );
+
+    case GLUT_TRANSPARENT_INDEX:
+        /*
+         * Return just anything, which is always defined as zero
+         */
+        return( 0 );
+
+    case GLUT_NORMAL_DAMAGED:
+        /*
+         * Actually I do not know. Maybe.
+         */
+        return( FALSE );
+
+    case GLUT_OVERLAY_DAMAGED:
+        /*
+         * Return minus one to mark that no layer is in use
+         */
+        return( -1 );
+#endif
+
+    default:
+        /*
+         * Complain to the user about the obvious bug
+         */
+        fgWarning( "glutLayerGet(): missing enum handle %i\n", eWhat );
+        break;
+    }
+
+    /*
+     * And fail. That's good. Programs do love failing.
+     */
+    return( -1 );
+}
+
+/*** END OF FILE ***/
diff --git a/src/freeglut_stroke_mono_roman.c b/src/freeglut_stroke_mono_roman.c
new file mode 100644 (file)
index 0000000..1c6aa4f
--- /dev/null
@@ -0,0 +1,2823 @@
+
+/* This file has been automatically generated by the genstroke utility. */
+
+#include "freeglut_internal.h"
+#ifdef TARGET_HOST_WIN32
+#pragma warning ( once:4305 )
+#endif
+/* char: 0x20 */
+
+static const SFG_StrokeStrip ch32st[] =
+{
+  { 0, NULL }
+};
+
+static const SFG_StrokeChar ch32 = {104.762,0,ch32st};
+
+/* char: 0x21 */
+
+static const SFG_StrokeVertex ch33st0[] =
+{
+ {52.381,100},
+ {52.381,33.3333}
+};
+
+static const SFG_StrokeVertex ch33st1[] =
+{
+ {52.381,9.5238},
+ {47.6191,4.7619},
+ {52.381,0},
+ {57.1429,4.7619},
+ {52.381,9.5238}
+};
+
+static const SFG_StrokeStrip ch33st[] =
+{
+ {2,ch33st0},
+ {5,ch33st1}
+};
+
+static const SFG_StrokeChar ch33 = {104.762,2,ch33st};
+
+/* char: 0x22 */
+
+static const SFG_StrokeVertex ch34st0[] =
+{
+ {33.3334,100},
+ {33.3334,66.6667}
+};
+
+static const SFG_StrokeVertex ch34st1[] =
+{
+ {71.4286,100},
+ {71.4286,66.6667}
+};
+
+static const SFG_StrokeStrip ch34st[] =
+{
+ {2,ch34st0},
+ {2,ch34st1}
+};
+
+static const SFG_StrokeChar ch34 = {104.762,2,ch34st};
+
+/* char: 0x23 */
+
+static const SFG_StrokeVertex ch35st0[] =
+{
+ {54.7619,119.048},
+ {21.4286,-33.3333}
+};
+
+static const SFG_StrokeVertex ch35st1[] =
+{
+ {83.3334,119.048},
+ {50,-33.3333}
+};
+
+static const SFG_StrokeVertex ch35st2[] =
+{
+ {21.4286,57.1429},
+ {88.0952,57.1429}
+};
+
+static const SFG_StrokeVertex ch35st3[] =
+{
+ {16.6667,28.5714},
+ {83.3334,28.5714}
+};
+
+static const SFG_StrokeStrip ch35st[] =
+{
+ {2,ch35st0},
+ {2,ch35st1},
+ {2,ch35st2},
+ {2,ch35st3}
+};
+
+static const SFG_StrokeChar ch35 = {104.762,4,ch35st};
+
+/* char: 0x24 */
+
+static const SFG_StrokeVertex ch36st0[] =
+{
+ {42.8571,119.048},
+ {42.8571,-19.0476}
+};
+
+static const SFG_StrokeVertex ch36st1[] =
+{
+ {61.9047,119.048},
+ {61.9047,-19.0476}
+};
+
+static const SFG_StrokeVertex ch36st2[] =
+{
+ {85.7143,85.7143},
+ {76.1905,95.2381},
+ {61.9047,100},
+ {42.8571,100},
+ {28.5714,95.2381},
+ {19.0476,85.7143},
+ {19.0476,76.1905},
+ {23.8095,66.6667},
+ {28.5714,61.9048},
+ {38.0952,57.1429},
+ {66.6666,47.619},
+ {76.1905,42.8571},
+ {80.9524,38.0952},
+ {85.7143,28.5714},
+ {85.7143,14.2857},
+ {76.1905,4.7619},
+ {61.9047,0},
+ {42.8571,0},
+ {28.5714,4.7619},
+ {19.0476,14.2857}
+};
+
+static const SFG_StrokeStrip ch36st[] =
+{
+ {2,ch36st0},
+ {2,ch36st1},
+ {20,ch36st2}
+};
+
+static const SFG_StrokeChar ch36 = {104.762,3,ch36st};
+
+/* char: 0x25 */
+
+static const SFG_StrokeVertex ch37st0[] =
+{
+ {95.2381,100},
+ {9.5238,0}
+};
+
+static const SFG_StrokeVertex ch37st1[] =
+{
+ {33.3333,100},
+ {42.8571,90.4762},
+ {42.8571,80.9524},
+ {38.0952,71.4286},
+ {28.5714,66.6667},
+ {19.0476,66.6667},
+ {9.5238,76.1905},
+ {9.5238,85.7143},
+ {14.2857,95.2381},
+ {23.8095,100},
+ {33.3333,100},
+ {42.8571,95.2381},
+ {57.1428,90.4762},
+ {71.4286,90.4762},
+ {85.7143,95.2381},
+ {95.2381,100}
+};
+
+static const SFG_StrokeVertex ch37st2[] =
+{
+ {76.1905,33.3333},
+ {66.6667,28.5714},
+ {61.9048,19.0476},
+ {61.9048,9.5238},
+ {71.4286,0},
+ {80.9524,0},
+ {90.4762,4.7619},
+ {95.2381,14.2857},
+ {95.2381,23.8095},
+ {85.7143,33.3333},
+ {76.1905,33.3333}
+};
+
+static const SFG_StrokeStrip ch37st[] =
+{
+ {2,ch37st0},
+ {16,ch37st1},
+ {11,ch37st2}
+};
+
+static const SFG_StrokeChar ch37 = {104.762,3,ch37st};
+
+/* char: 0x26 */
+
+static const SFG_StrokeVertex ch38st0[] =
+{
+ {100,57.1429},
+ {100,61.9048},
+ {95.2381,66.6667},
+ {90.4762,66.6667},
+ {85.7143,61.9048},
+ {80.9524,52.381},
+ {71.4286,28.5714},
+ {61.9048,14.2857},
+ {52.3809,4.7619},
+ {42.8571,0},
+ {23.8095,0},
+ {14.2857,4.7619},
+ {9.5238,9.5238},
+ {4.7619,19.0476},
+ {4.7619,28.5714},
+ {9.5238,38.0952},
+ {14.2857,42.8571},
+ {47.619,61.9048},
+ {52.3809,66.6667},
+ {57.1429,76.1905},
+ {57.1429,85.7143},
+ {52.3809,95.2381},
+ {42.8571,100},
+ {33.3333,95.2381},
+ {28.5714,85.7143},
+ {28.5714,76.1905},
+ {33.3333,61.9048},
+ {42.8571,47.619},
+ {66.6667,14.2857},
+ {76.1905,4.7619},
+ {85.7143,0},
+ {95.2381,0},
+ {100,4.7619},
+ {100,9.5238}
+};
+
+static const SFG_StrokeStrip ch38st[] =
+{
+ {34,ch38st0}
+};
+
+static const SFG_StrokeChar ch38 = {104.762,1,ch38st};
+
+/* char: 0x27 */
+
+static const SFG_StrokeVertex ch39st0[] =
+{
+ {52.381,100},
+ {52.381,66.6667}
+};
+
+static const SFG_StrokeStrip ch39st[] =
+{
+ {2,ch39st0}
+};
+
+static const SFG_StrokeChar ch39 = {104.762,1,ch39st};
+
+/* char: 0x28 */
+
+static const SFG_StrokeVertex ch40st0[] =
+{
+ {69.0476,119.048},
+ {59.5238,109.524},
+ {50,95.2381},
+ {40.4762,76.1905},
+ {35.7143,52.381},
+ {35.7143,33.3333},
+ {40.4762,9.5238},
+ {50,-9.5238},
+ {59.5238,-23.8095},
+ {69.0476,-33.3333}
+};
+
+static const SFG_StrokeStrip ch40st[] =
+{
+ {10,ch40st0}
+};
+
+static const SFG_StrokeChar ch40 = {104.762,1,ch40st};
+
+/* char: 0x29 */
+
+static const SFG_StrokeVertex ch41st0[] =
+{
+ {35.7143,119.048},
+ {45.2381,109.524},
+ {54.7619,95.2381},
+ {64.2857,76.1905},
+ {69.0476,52.381},
+ {69.0476,33.3333},
+ {64.2857,9.5238},
+ {54.7619,-9.5238},
+ {45.2381,-23.8095},
+ {35.7143,-33.3333}
+};
+
+static const SFG_StrokeStrip ch41st[] =
+{
+ {10,ch41st0}
+};
+
+static const SFG_StrokeChar ch41 = {104.762,1,ch41st};
+
+/* char: 0x2a */
+
+static const SFG_StrokeVertex ch42st0[] =
+{
+ {52.381,71.4286},
+ {52.381,14.2857}
+};
+
+static const SFG_StrokeVertex ch42st1[] =
+{
+ {28.5715,57.1429},
+ {76.1905,28.5714}
+};
+
+static const SFG_StrokeVertex ch42st2[] =
+{
+ {76.1905,57.1429},
+ {28.5715,28.5714}
+};
+
+static const SFG_StrokeStrip ch42st[] =
+{
+ {2,ch42st0},
+ {2,ch42st1},
+ {2,ch42st2}
+};
+
+static const SFG_StrokeChar ch42 = {104.762,3,ch42st};
+
+/* char: 0x2b */
+
+static const SFG_StrokeVertex ch43st0[] =
+{
+ {52.3809,85.7143},
+ {52.3809,0}
+};
+
+static const SFG_StrokeVertex ch43st1[] =
+{
+ {9.5238,42.8571},
+ {95.2381,42.8571}
+};
+
+static const SFG_StrokeStrip ch43st[] =
+{
+ {2,ch43st0},
+ {2,ch43st1}
+};
+
+static const SFG_StrokeChar ch43 = {104.762,2,ch43st};
+
+/* char: 0x2c */
+
+static const SFG_StrokeVertex ch44st0[] =
+{
+ {57.1429,4.7619},
+ {52.381,0},
+ {47.6191,4.7619},
+ {52.381,9.5238},
+ {57.1429,4.7619},
+ {57.1429,-4.7619},
+ {52.381,-14.2857},
+ {47.6191,-19.0476}
+};
+
+static const SFG_StrokeStrip ch44st[] =
+{
+ {8,ch44st0}
+};
+
+static const SFG_StrokeChar ch44 = {104.762,1,ch44st};
+
+/* char: 0x2d */
+
+static const SFG_StrokeVertex ch45st0[] =
+{
+ {9.5238,42.8571},
+ {95.2381,42.8571}
+};
+
+static const SFG_StrokeStrip ch45st[] =
+{
+ {2,ch45st0}
+};
+
+static const SFG_StrokeChar ch45 = {104.762,1,ch45st};
+
+/* char: 0x2e */
+
+static const SFG_StrokeVertex ch46st0[] =
+{
+ {52.381,9.5238},
+ {47.6191,4.7619},
+ {52.381,0},
+ {57.1429,4.7619},
+ {52.381,9.5238}
+};
+
+static const SFG_StrokeStrip ch46st[] =
+{
+ {5,ch46st0}
+};
+
+static const SFG_StrokeChar ch46 = {104.762,1,ch46st};
+
+/* char: 0x2f */
+
+static const SFG_StrokeVertex ch47st0[] =
+{
+ {19.0476,-14.2857},
+ {85.7143,100}
+};
+
+static const SFG_StrokeStrip ch47st[] =
+{
+ {2,ch47st0}
+};
+
+static const SFG_StrokeChar ch47 = {104.762,1,ch47st};
+
+/* char: 0x30 */
+
+static const SFG_StrokeVertex ch48st0[] =
+{
+ {47.619,100},
+ {33.3333,95.2381},
+ {23.8095,80.9524},
+ {19.0476,57.1429},
+ {19.0476,42.8571},
+ {23.8095,19.0476},
+ {33.3333,4.7619},
+ {47.619,0},
+ {57.1428,0},
+ {71.4286,4.7619},
+ {80.9524,19.0476},
+ {85.7143,42.8571},
+ {85.7143,57.1429},
+ {80.9524,80.9524},
+ {71.4286,95.2381},
+ {57.1428,100},
+ {47.619,100}
+};
+
+static const SFG_StrokeStrip ch48st[] =
+{
+ {17,ch48st0}
+};
+
+static const SFG_StrokeChar ch48 = {104.762,1,ch48st};
+
+/* char: 0x31 */
+
+static const SFG_StrokeVertex ch49st0[] =
+{
+ {40.4762,80.9524},
+ {50,85.7143},
+ {64.2857,100},
+ {64.2857,0}
+};
+
+static const SFG_StrokeStrip ch49st[] =
+{
+ {4,ch49st0}
+};
+
+static const SFG_StrokeChar ch49 = {104.762,1,ch49st};
+
+/* char: 0x32 */
+
+static const SFG_StrokeVertex ch50st0[] =
+{
+ {23.8095,76.1905},
+ {23.8095,80.9524},
+ {28.5714,90.4762},
+ {33.3333,95.2381},
+ {42.8571,100},
+ {61.9047,100},
+ {71.4286,95.2381},
+ {76.1905,90.4762},
+ {80.9524,80.9524},
+ {80.9524,71.4286},
+ {76.1905,61.9048},
+ {66.6666,47.619},
+ {19.0476,0},
+ {85.7143,0}
+};
+
+static const SFG_StrokeStrip ch50st[] =
+{
+ {14,ch50st0}
+};
+
+static const SFG_StrokeChar ch50 = {104.762,1,ch50st};
+
+/* char: 0x33 */
+
+static const SFG_StrokeVertex ch51st0[] =
+{
+ {28.5714,100},
+ {80.9524,100},
+ {52.3809,61.9048},
+ {66.6666,61.9048},
+ {76.1905,57.1429},
+ {80.9524,52.381},
+ {85.7143,38.0952},
+ {85.7143,28.5714},
+ {80.9524,14.2857},
+ {71.4286,4.7619},
+ {57.1428,0},
+ {42.8571,0},
+ {28.5714,4.7619},
+ {23.8095,9.5238},
+ {19.0476,19.0476}
+};
+
+static const SFG_StrokeStrip ch51st[] =
+{
+ {15,ch51st0}
+};
+
+static const SFG_StrokeChar ch51 = {104.762,1,ch51st};
+
+/* char: 0x34 */
+
+static const SFG_StrokeVertex ch52st0[] =
+{
+ {64.2857,100},
+ {16.6667,33.3333},
+ {88.0952,33.3333}
+};
+
+static const SFG_StrokeVertex ch52st1[] =
+{
+ {64.2857,100},
+ {64.2857,0}
+};
+
+static const SFG_StrokeStrip ch52st[] =
+{
+ {3,ch52st0},
+ {2,ch52st1}
+};
+
+static const SFG_StrokeChar ch52 = {104.762,2,ch52st};
+
+/* char: 0x35 */
+
+static const SFG_StrokeVertex ch53st0[] =
+{
+ {76.1905,100},
+ {28.5714,100},
+ {23.8095,57.1429},
+ {28.5714,61.9048},
+ {42.8571,66.6667},
+ {57.1428,66.6667},
+ {71.4286,61.9048},
+ {80.9524,52.381},
+ {85.7143,38.0952},
+ {85.7143,28.5714},
+ {80.9524,14.2857},
+ {71.4286,4.7619},
+ {57.1428,0},
+ {42.8571,0},
+ {28.5714,4.7619},
+ {23.8095,9.5238},
+ {19.0476,19.0476}
+};
+
+static const SFG_StrokeStrip ch53st[] =
+{
+ {17,ch53st0}
+};
+
+static const SFG_StrokeChar ch53 = {104.762,1,ch53st};
+
+/* char: 0x36 */
+
+static const SFG_StrokeVertex ch54st0[] =
+{
+ {78.5714,85.7143},
+ {73.8096,95.2381},
+ {59.5238,100},
+ {50,100},
+ {35.7143,95.2381},
+ {26.1905,80.9524},
+ {21.4286,57.1429},
+ {21.4286,33.3333},
+ {26.1905,14.2857},
+ {35.7143,4.7619},
+ {50,0},
+ {54.7619,0},
+ {69.0476,4.7619},
+ {78.5714,14.2857},
+ {83.3334,28.5714},
+ {83.3334,33.3333},
+ {78.5714,47.619},
+ {69.0476,57.1429},
+ {54.7619,61.9048},
+ {50,61.9048},
+ {35.7143,57.1429},
+ {26.1905,47.619},
+ {21.4286,33.3333}
+};
+
+static const SFG_StrokeStrip ch54st[] =
+{
+ {23,ch54st0}
+};
+
+static const SFG_StrokeChar ch54 = {104.762,1,ch54st};
+
+/* char: 0x37 */
+
+static const SFG_StrokeVertex ch55st0[] =
+{
+ {85.7143,100},
+ {38.0952,0}
+};
+
+static const SFG_StrokeVertex ch55st1[] =
+{
+ {19.0476,100},
+ {85.7143,100}
+};
+
+static const SFG_StrokeStrip ch55st[] =
+{
+ {2,ch55st0},
+ {2,ch55st1}
+};
+
+static const SFG_StrokeChar ch55 = {104.762,2,ch55st};
+
+/* char: 0x38 */
+
+static const SFG_StrokeVertex ch56st0[] =
+{
+ {42.8571,100},
+ {28.5714,95.2381},
+ {23.8095,85.7143},
+ {23.8095,76.1905},
+ {28.5714,66.6667},
+ {38.0952,61.9048},
+ {57.1428,57.1429},
+ {71.4286,52.381},
+ {80.9524,42.8571},
+ {85.7143,33.3333},
+ {85.7143,19.0476},
+ {80.9524,9.5238},
+ {76.1905,4.7619},
+ {61.9047,0},
+ {42.8571,0},
+ {28.5714,4.7619},
+ {23.8095,9.5238},
+ {19.0476,19.0476},
+ {19.0476,33.3333},
+ {23.8095,42.8571},
+ {33.3333,52.381},
+ {47.619,57.1429},
+ {66.6666,61.9048},
+ {76.1905,66.6667},
+ {80.9524,76.1905},
+ {80.9524,85.7143},
+ {76.1905,95.2381},
+ {61.9047,100},
+ {42.8571,100}
+};
+
+static const SFG_StrokeStrip ch56st[] =
+{
+ {29,ch56st0}
+};
+
+static const SFG_StrokeChar ch56 = {104.762,1,ch56st};
+
+/* char: 0x39 */
+
+static const SFG_StrokeVertex ch57st0[] =
+{
+ {83.3334,66.6667},
+ {78.5714,52.381},
+ {69.0476,42.8571},
+ {54.7619,38.0952},
+ {50,38.0952},
+ {35.7143,42.8571},
+ {26.1905,52.381},
+ {21.4286,66.6667},
+ {21.4286,71.4286},
+ {26.1905,85.7143},
+ {35.7143,95.2381},
+ {50,100},
+ {54.7619,100},
+ {69.0476,95.2381},
+ {78.5714,85.7143},
+ {83.3334,66.6667},
+ {83.3334,42.8571},
+ {78.5714,19.0476},
+ {69.0476,4.7619},
+ {54.7619,0},
+ {45.2381,0},
+ {30.9524,4.7619},
+ {26.1905,14.2857}
+};
+
+static const SFG_StrokeStrip ch57st[] =
+{
+ {23,ch57st0}
+};
+
+static const SFG_StrokeChar ch57 = {104.762,1,ch57st};
+
+/* char: 0x3a */
+
+static const SFG_StrokeVertex ch58st0[] =
+{
+ {52.381,66.6667},
+ {47.6191,61.9048},
+ {52.381,57.1429},
+ {57.1429,61.9048},
+ {52.381,66.6667}
+};
+
+static const SFG_StrokeVertex ch58st1[] =
+{
+ {52.381,9.5238},
+ {47.6191,4.7619},
+ {52.381,0},
+ {57.1429,4.7619},
+ {52.381,9.5238}
+};
+
+static const SFG_StrokeStrip ch58st[] =
+{
+ {5,ch58st0},
+ {5,ch58st1}
+};
+
+static const SFG_StrokeChar ch58 = {104.762,2,ch58st};
+
+/* char: 0x3b */
+
+static const SFG_StrokeVertex ch59st0[] =
+{
+ {52.381,66.6667},
+ {47.6191,61.9048},
+ {52.381,57.1429},
+ {57.1429,61.9048},
+ {52.381,66.6667}
+};
+
+static const SFG_StrokeVertex ch59st1[] =
+{
+ {57.1429,4.7619},
+ {52.381,0},
+ {47.6191,4.7619},
+ {52.381,9.5238},
+ {57.1429,4.7619},
+ {57.1429,-4.7619},
+ {52.381,-14.2857},
+ {47.6191,-19.0476}
+};
+
+static const SFG_StrokeStrip ch59st[] =
+{
+ {5,ch59st0},
+ {8,ch59st1}
+};
+
+static const SFG_StrokeChar ch59 = {104.762,2,ch59st};
+
+/* char: 0x3c */
+
+static const SFG_StrokeVertex ch60st0[] =
+{
+ {90.4762,85.7143},
+ {14.2857,42.8571},
+ {90.4762,0}
+};
+
+static const SFG_StrokeStrip ch60st[] =
+{
+ {3,ch60st0}
+};
+
+static const SFG_StrokeChar ch60 = {104.762,1,ch60st};
+
+/* char: 0x3d */
+
+static const SFG_StrokeVertex ch61st0[] =
+{
+ {9.5238,57.1429},
+ {95.2381,57.1429}
+};
+
+static const SFG_StrokeVertex ch61st1[] =
+{
+ {9.5238,28.5714},
+ {95.2381,28.5714}
+};
+
+static const SFG_StrokeStrip ch61st[] =
+{
+ {2,ch61st0},
+ {2,ch61st1}
+};
+
+static const SFG_StrokeChar ch61 = {104.762,2,ch61st};
+
+/* char: 0x3e */
+
+static const SFG_StrokeVertex ch62st0[] =
+{
+ {14.2857,85.7143},
+ {90.4762,42.8571},
+ {14.2857,0}
+};
+
+static const SFG_StrokeStrip ch62st[] =
+{
+ {3,ch62st0}
+};
+
+static const SFG_StrokeChar ch62 = {104.762,1,ch62st};
+
+/* char: 0x3f */
+
+static const SFG_StrokeVertex ch63st0[] =
+{
+ {23.8095,76.1905},
+ {23.8095,80.9524},
+ {28.5714,90.4762},
+ {33.3333,95.2381},
+ {42.8571,100},
+ {61.9047,100},
+ {71.4285,95.2381},
+ {76.1905,90.4762},
+ {80.9524,80.9524},
+ {80.9524,71.4286},
+ {76.1905,61.9048},
+ {71.4285,57.1429},
+ {52.3809,47.619},
+ {52.3809,33.3333}
+};
+
+static const SFG_StrokeVertex ch63st1[] =
+{
+ {52.3809,9.5238},
+ {47.619,4.7619},
+ {52.3809,0},
+ {57.1428,4.7619},
+ {52.3809,9.5238}
+};
+
+static const SFG_StrokeStrip ch63st[] =
+{
+ {14,ch63st0},
+ {5,ch63st1}
+};
+
+static const SFG_StrokeChar ch63 = {104.762,2,ch63st};
+
+/* char: 0x40 */
+
+static const SFG_StrokeVertex ch64st0[] =
+{
+ {64.2857,52.381},
+ {54.7619,57.1429},
+ {45.2381,57.1429},
+ {40.4762,47.619},
+ {40.4762,42.8571},
+ {45.2381,33.3333},
+ {54.7619,33.3333},
+ {64.2857,38.0952}
+};
+
+static const SFG_StrokeVertex ch64st1[] =
+{
+ {64.2857,57.1429},
+ {64.2857,38.0952},
+ {69.0476,33.3333},
+ {78.5714,33.3333},
+ {83.3334,42.8571},
+ {83.3334,47.619},
+ {78.5714,61.9048},
+ {69.0476,71.4286},
+ {54.7619,76.1905},
+ {50,76.1905},
+ {35.7143,71.4286},
+ {26.1905,61.9048},
+ {21.4286,47.619},
+ {21.4286,42.8571},
+ {26.1905,28.5714},
+ {35.7143,19.0476},
+ {50,14.2857},
+ {54.7619,14.2857},
+ {69.0476,19.0476}
+};
+
+static const SFG_StrokeStrip ch64st[] =
+{
+ {8,ch64st0},
+ {19,ch64st1}
+};
+
+static const SFG_StrokeChar ch64 = {104.762,2,ch64st};
+
+/* char: 0x41 */
+
+static const SFG_StrokeVertex ch65st0[] =
+{
+ {52.3809,100},
+ {14.2857,0}
+};
+
+static const SFG_StrokeVertex ch65st1[] =
+{
+ {52.3809,100},
+ {90.4762,0}
+};
+
+static const SFG_StrokeVertex ch65st2[] =
+{
+ {28.5714,33.3333},
+ {76.1905,33.3333}
+};
+
+static const SFG_StrokeStrip ch65st[] =
+{
+ {2,ch65st0},
+ {2,ch65st1},
+ {2,ch65st2}
+};
+
+static const SFG_StrokeChar ch65 = {104.762,3,ch65st};
+
+/* char: 0x42 */
+
+static const SFG_StrokeVertex ch66st0[] =
+{
+ {19.0476,100},
+ {19.0476,0}
+};
+
+static const SFG_StrokeVertex ch66st1[] =
+{
+ {19.0476,100},
+ {61.9047,100},
+ {76.1905,95.2381},
+ {80.9524,90.4762},
+ {85.7143,80.9524},
+ {85.7143,71.4286},
+ {80.9524,61.9048},
+ {76.1905,57.1429},
+ {61.9047,52.381}
+};
+
+static const SFG_StrokeVertex ch66st2[] =
+{
+ {19.0476,52.381},
+ {61.9047,52.381},
+ {76.1905,47.619},
+ {80.9524,42.8571},
+ {85.7143,33.3333},
+ {85.7143,19.0476},
+ {80.9524,9.5238},
+ {76.1905,4.7619},
+ {61.9047,0},
+ {19.0476,0}
+};
+
+static const SFG_StrokeStrip ch66st[] =
+{
+ {2,ch66st0},
+ {9,ch66st1},
+ {10,ch66st2}
+};
+
+static const SFG_StrokeChar ch66 = {104.762,3,ch66st};
+
+/* char: 0x43 */
+
+static const SFG_StrokeVertex ch67st0[] =
+{
+ {88.0952,76.1905},
+ {83.3334,85.7143},
+ {73.8096,95.2381},
+ {64.2857,100},
+ {45.2381,100},
+ {35.7143,95.2381},
+ {26.1905,85.7143},
+ {21.4286,76.1905},
+ {16.6667,61.9048},
+ {16.6667,38.0952},
+ {21.4286,23.8095},
+ {26.1905,14.2857},
+ {35.7143,4.7619},
+ {45.2381,0},
+ {64.2857,0},
+ {73.8096,4.7619},
+ {83.3334,14.2857},
+ {88.0952,23.8095}
+};
+
+static const SFG_StrokeStrip ch67st[] =
+{
+ {18,ch67st0}
+};
+
+static const SFG_StrokeChar ch67 = {104.762,1,ch67st};
+
+/* char: 0x44 */
+
+static const SFG_StrokeVertex ch68st0[] =
+{
+ {19.0476,100},
+ {19.0476,0}
+};
+
+static const SFG_StrokeVertex ch68st1[] =
+{
+ {19.0476,100},
+ {52.3809,100},
+ {66.6666,95.2381},
+ {76.1905,85.7143},
+ {80.9524,76.1905},
+ {85.7143,61.9048},
+ {85.7143,38.0952},
+ {80.9524,23.8095},
+ {76.1905,14.2857},
+ {66.6666,4.7619},
+ {52.3809,0},
+ {19.0476,0}
+};
+
+static const SFG_StrokeStrip ch68st[] =
+{
+ {2,ch68st0},
+ {12,ch68st1}
+};
+
+static const SFG_StrokeChar ch68 = {104.762,2,ch68st};
+
+/* char: 0x45 */
+
+static const SFG_StrokeVertex ch69st0[] =
+{
+ {21.4286,100},
+ {21.4286,0}
+};
+
+static const SFG_StrokeVertex ch69st1[] =
+{
+ {21.4286,100},
+ {83.3334,100}
+};
+
+static const SFG_StrokeVertex ch69st2[] =
+{
+ {21.4286,52.381},
+ {59.5238,52.381}
+};
+
+static const SFG_StrokeVertex ch69st3[] =
+{
+ {21.4286,0},
+ {83.3334,0}
+};
+
+static const SFG_StrokeStrip ch69st[] =
+{
+ {2,ch69st0},
+ {2,ch69st1},
+ {2,ch69st2},
+ {2,ch69st3}
+};
+
+static const SFG_StrokeChar ch69 = {104.762,4,ch69st};
+
+/* char: 0x46 */
+
+static const SFG_StrokeVertex ch70st0[] =
+{
+ {21.4286,100},
+ {21.4286,0}
+};
+
+static const SFG_StrokeVertex ch70st1[] =
+{
+ {21.4286,100},
+ {83.3334,100}
+};
+
+static const SFG_StrokeVertex ch70st2[] =
+{
+ {21.4286,52.381},
+ {59.5238,52.381}
+};
+
+static const SFG_StrokeStrip ch70st[] =
+{
+ {2,ch70st0},
+ {2,ch70st1},
+ {2,ch70st2}
+};
+
+static const SFG_StrokeChar ch70 = {104.762,3,ch70st};
+
+/* char: 0x47 */
+
+static const SFG_StrokeVertex ch71st0[] =
+{
+ {88.0952,76.1905},
+ {83.3334,85.7143},
+ {73.8096,95.2381},
+ {64.2857,100},
+ {45.2381,100},
+ {35.7143,95.2381},
+ {26.1905,85.7143},
+ {21.4286,76.1905},
+ {16.6667,61.9048},
+ {16.6667,38.0952},
+ {21.4286,23.8095},
+ {26.1905,14.2857},
+ {35.7143,4.7619},
+ {45.2381,0},
+ {64.2857,0},
+ {73.8096,4.7619},
+ {83.3334,14.2857},
+ {88.0952,23.8095},
+ {88.0952,38.0952}
+};
+
+static const SFG_StrokeVertex ch71st1[] =
+{
+ {64.2857,38.0952},
+ {88.0952,38.0952}
+};
+
+static const SFG_StrokeStrip ch71st[] =
+{
+ {19,ch71st0},
+ {2,ch71st1}
+};
+
+static const SFG_StrokeChar ch71 = {104.762,2,ch71st};
+
+/* char: 0x48 */
+
+static const SFG_StrokeVertex ch72st0[] =
+{
+ {19.0476,100},
+ {19.0476,0}
+};
+
+static const SFG_StrokeVertex ch72st1[] =
+{
+ {85.7143,100},
+ {85.7143,0}
+};
+
+static const SFG_StrokeVertex ch72st2[] =
+{
+ {19.0476,52.381},
+ {85.7143,52.381}
+};
+
+static const SFG_StrokeStrip ch72st[] =
+{
+ {2,ch72st0},
+ {2,ch72st1},
+ {2,ch72st2}
+};
+
+static const SFG_StrokeChar ch72 = {104.762,3,ch72st};
+
+/* char: 0x49 */
+
+static const SFG_StrokeVertex ch73st0[] =
+{
+ {52.381,100},
+ {52.381,0}
+};
+
+static const SFG_StrokeStrip ch73st[] =
+{
+ {2,ch73st0}
+};
+
+static const SFG_StrokeChar ch73 = {104.762,1,ch73st};
+
+/* char: 0x4a */
+
+static const SFG_StrokeVertex ch74st0[] =
+{
+ {76.1905,100},
+ {76.1905,23.8095},
+ {71.4286,9.5238},
+ {66.6667,4.7619},
+ {57.1429,0},
+ {47.6191,0},
+ {38.0953,4.7619},
+ {33.3334,9.5238},
+ {28.5715,23.8095},
+ {28.5715,33.3333}
+};
+
+static const SFG_StrokeStrip ch74st[] =
+{
+ {10,ch74st0}
+};
+
+static const SFG_StrokeChar ch74 = {104.762,1,ch74st};
+
+/* char: 0x4b */
+
+static const SFG_StrokeVertex ch75st0[] =
+{
+ {19.0476,100},
+ {19.0476,0}
+};
+
+static const SFG_StrokeVertex ch75st1[] =
+{
+ {85.7143,100},
+ {19.0476,33.3333}
+};
+
+static const SFG_StrokeVertex ch75st2[] =
+{
+ {42.8571,57.1429},
+ {85.7143,0}
+};
+
+static const SFG_StrokeStrip ch75st[] =
+{
+ {2,ch75st0},
+ {2,ch75st1},
+ {2,ch75st2}
+};
+
+static const SFG_StrokeChar ch75 = {104.762,3,ch75st};
+
+/* char: 0x4c */
+
+static const SFG_StrokeVertex ch76st0[] =
+{
+ {23.8095,100},
+ {23.8095,0}
+};
+
+static const SFG_StrokeVertex ch76st1[] =
+{
+ {23.8095,0},
+ {80.9524,0}
+};
+
+static const SFG_StrokeStrip ch76st[] =
+{
+ {2,ch76st0},
+ {2,ch76st1}
+};
+
+static const SFG_StrokeChar ch76 = {104.762,2,ch76st};
+
+/* char: 0x4d */
+
+static const SFG_StrokeVertex ch77st0[] =
+{
+ {14.2857,100},
+ {14.2857,0}
+};
+
+static const SFG_StrokeVertex ch77st1[] =
+{
+ {14.2857,100},
+ {52.3809,0}
+};
+
+static const SFG_StrokeVertex ch77st2[] =
+{
+ {90.4762,100},
+ {52.3809,0}
+};
+
+static const SFG_StrokeVertex ch77st3[] =
+{
+ {90.4762,100},
+ {90.4762,0}
+};
+
+static const SFG_StrokeStrip ch77st[] =
+{
+ {2,ch77st0},
+ {2,ch77st1},
+ {2,ch77st2},
+ {2,ch77st3}
+};
+
+static const SFG_StrokeChar ch77 = {104.762,4,ch77st};
+
+/* char: 0x4e */
+
+static const SFG_StrokeVertex ch78st0[] =
+{
+ {19.0476,100},
+ {19.0476,0}
+};
+
+static const SFG_StrokeVertex ch78st1[] =
+{
+ {19.0476,100},
+ {85.7143,0}
+};
+
+static const SFG_StrokeVertex ch78st2[] =
+{
+ {85.7143,100},
+ {85.7143,0}
+};
+
+static const SFG_StrokeStrip ch78st[] =
+{
+ {2,ch78st0},
+ {2,ch78st1},
+ {2,ch78st2}
+};
+
+static const SFG_StrokeChar ch78 = {104.762,3,ch78st};
+
+/* char: 0x4f */
+
+static const SFG_StrokeVertex ch79st0[] =
+{
+ {42.8571,100},
+ {33.3333,95.2381},
+ {23.8095,85.7143},
+ {19.0476,76.1905},
+ {14.2857,61.9048},
+ {14.2857,38.0952},
+ {19.0476,23.8095},
+ {23.8095,14.2857},
+ {33.3333,4.7619},
+ {42.8571,0},
+ {61.9047,0},
+ {71.4286,4.7619},
+ {80.9524,14.2857},
+ {85.7143,23.8095},
+ {90.4762,38.0952},
+ {90.4762,61.9048},
+ {85.7143,76.1905},
+ {80.9524,85.7143},
+ {71.4286,95.2381},
+ {61.9047,100},
+ {42.8571,100}
+};
+
+static const SFG_StrokeStrip ch79st[] =
+{
+ {21,ch79st0}
+};
+
+static const SFG_StrokeChar ch79 = {104.762,1,ch79st};
+
+/* char: 0x50 */
+
+static const SFG_StrokeVertex ch80st0[] =
+{
+ {19.0476,100},
+ {19.0476,0}
+};
+
+static const SFG_StrokeVertex ch80st1[] =
+{
+ {19.0476,100},
+ {61.9047,100},
+ {76.1905,95.2381},
+ {80.9524,90.4762},
+ {85.7143,80.9524},
+ {85.7143,66.6667},
+ {80.9524,57.1429},
+ {76.1905,52.381},
+ {61.9047,47.619},
+ {19.0476,47.619}
+};
+
+static const SFG_StrokeStrip ch80st[] =
+{
+ {2,ch80st0},
+ {10,ch80st1}
+};
+
+static const SFG_StrokeChar ch80 = {104.762,2,ch80st};
+
+/* char: 0x51 */
+
+static const SFG_StrokeVertex ch81st0[] =
+{
+ {42.8571,100},
+ {33.3333,95.2381},
+ {23.8095,85.7143},
+ {19.0476,76.1905},
+ {14.2857,61.9048},
+ {14.2857,38.0952},
+ {19.0476,23.8095},
+ {23.8095,14.2857},
+ {33.3333,4.7619},
+ {42.8571,0},
+ {61.9047,0},
+ {71.4286,4.7619},
+ {80.9524,14.2857},
+ {85.7143,23.8095},
+ {90.4762,38.0952},
+ {90.4762,61.9048},
+ {85.7143,76.1905},
+ {80.9524,85.7143},
+ {71.4286,95.2381},
+ {61.9047,100},
+ {42.8571,100}
+};
+
+static const SFG_StrokeVertex ch81st1[] =
+{
+ {57.1428,19.0476},
+ {85.7143,-9.5238}
+};
+
+static const SFG_StrokeStrip ch81st[] =
+{
+ {21,ch81st0},
+ {2,ch81st1}
+};
+
+static const SFG_StrokeChar ch81 = {104.762,2,ch81st};
+
+/* char: 0x52 */
+
+static const SFG_StrokeVertex ch82st0[] =
+{
+ {19.0476,100},
+ {19.0476,0}
+};
+
+static const SFG_StrokeVertex ch82st1[] =
+{
+ {19.0476,100},
+ {61.9047,100},
+ {76.1905,95.2381},
+ {80.9524,90.4762},
+ {85.7143,80.9524},
+ {85.7143,71.4286},
+ {80.9524,61.9048},
+ {76.1905,57.1429},
+ {61.9047,52.381},
+ {19.0476,52.381}
+};
+
+static const SFG_StrokeVertex ch82st2[] =
+{
+ {52.3809,52.381},
+ {85.7143,0}
+};
+
+static const SFG_StrokeStrip ch82st[] =
+{
+ {2,ch82st0},
+ {10,ch82st1},
+ {2,ch82st2}
+};
+
+static const SFG_StrokeChar ch82 = {104.762,3,ch82st};
+
+/* char: 0x53 */
+
+static const SFG_StrokeVertex ch83st0[] =
+{
+ {85.7143,85.7143},
+ {76.1905,95.2381},
+ {61.9047,100},
+ {42.8571,100},
+ {28.5714,95.2381},
+ {19.0476,85.7143},
+ {19.0476,76.1905},
+ {23.8095,66.6667},
+ {28.5714,61.9048},
+ {38.0952,57.1429},
+ {66.6666,47.619},
+ {76.1905,42.8571},
+ {80.9524,38.0952},
+ {85.7143,28.5714},
+ {85.7143,14.2857},
+ {76.1905,4.7619},
+ {61.9047,0},
+ {42.8571,0},
+ {28.5714,4.7619},
+ {19.0476,14.2857}
+};
+
+static const SFG_StrokeStrip ch83st[] =
+{
+ {20,ch83st0}
+};
+
+static const SFG_StrokeChar ch83 = {104.762,1,ch83st};
+
+/* char: 0x54 */
+
+static const SFG_StrokeVertex ch84st0[] =
+{
+ {52.3809,100},
+ {52.3809,0}
+};
+
+static const SFG_StrokeVertex ch84st1[] =
+{
+ {19.0476,100},
+ {85.7143,100}
+};
+
+static const SFG_StrokeStrip ch84st[] =
+{
+ {2,ch84st0},
+ {2,ch84st1}
+};
+
+static const SFG_StrokeChar ch84 = {104.762,2,ch84st};
+
+/* char: 0x55 */
+
+static const SFG_StrokeVertex ch85st0[] =
+{
+ {19.0476,100},
+ {19.0476,28.5714},
+ {23.8095,14.2857},
+ {33.3333,4.7619},
+ {47.619,0},
+ {57.1428,0},
+ {71.4286,4.7619},
+ {80.9524,14.2857},
+ {85.7143,28.5714},
+ {85.7143,100}
+};
+
+static const SFG_StrokeStrip ch85st[] =
+{
+ {10,ch85st0}
+};
+
+static const SFG_StrokeChar ch85 = {104.762,1,ch85st};
+
+/* char: 0x56 */
+
+static const SFG_StrokeVertex ch86st0[] =
+{
+ {14.2857,100},
+ {52.3809,0}
+};
+
+static const SFG_StrokeVertex ch86st1[] =
+{
+ {90.4762,100},
+ {52.3809,0}
+};
+
+static const SFG_StrokeStrip ch86st[] =
+{
+ {2,ch86st0},
+ {2,ch86st1}
+};
+
+static const SFG_StrokeChar ch86 = {104.762,2,ch86st};
+
+/* char: 0x57 */
+
+static const SFG_StrokeVertex ch87st0[] =
+{
+ {4.7619,100},
+ {28.5714,0}
+};
+
+static const SFG_StrokeVertex ch87st1[] =
+{
+ {52.3809,100},
+ {28.5714,0}
+};
+
+static const SFG_StrokeVertex ch87st2[] =
+{
+ {52.3809,100},
+ {76.1905,0}
+};
+
+static const SFG_StrokeVertex ch87st3[] =
+{
+ {100,100},
+ {76.1905,0}
+};
+
+static const SFG_StrokeStrip ch87st[] =
+{
+ {2,ch87st0},
+ {2,ch87st1},
+ {2,ch87st2},
+ {2,ch87st3}
+};
+
+static const SFG_StrokeChar ch87 = {104.762,4,ch87st};
+
+/* char: 0x58 */
+
+static const SFG_StrokeVertex ch88st0[] =
+{
+ {19.0476,100},
+ {85.7143,0}
+};
+
+static const SFG_StrokeVertex ch88st1[] =
+{
+ {85.7143,100},
+ {19.0476,0}
+};
+
+static const SFG_StrokeStrip ch88st[] =
+{
+ {2,ch88st0},
+ {2,ch88st1}
+};
+
+static const SFG_StrokeChar ch88 = {104.762,2,ch88st};
+
+/* char: 0x59 */
+
+static const SFG_StrokeVertex ch89st0[] =
+{
+ {14.2857,100},
+ {52.3809,52.381},
+ {52.3809,0}
+};
+
+static const SFG_StrokeVertex ch89st1[] =
+{
+ {90.4762,100},
+ {52.3809,52.381}
+};
+
+static const SFG_StrokeStrip ch89st[] =
+{
+ {3,ch89st0},
+ {2,ch89st1}
+};
+
+static const SFG_StrokeChar ch89 = {104.762,2,ch89st};
+
+/* char: 0x5a */
+
+static const SFG_StrokeVertex ch90st0[] =
+{
+ {85.7143,100},
+ {19.0476,0}
+};
+
+static const SFG_StrokeVertex ch90st1[] =
+{
+ {19.0476,100},
+ {85.7143,100}
+};
+
+static const SFG_StrokeVertex ch90st2[] =
+{
+ {19.0476,0},
+ {85.7143,0}
+};
+
+static const SFG_StrokeStrip ch90st[] =
+{
+ {2,ch90st0},
+ {2,ch90st1},
+ {2,ch90st2}
+};
+
+static const SFG_StrokeChar ch90 = {104.762,3,ch90st};
+
+/* char: 0x5b */
+
+static const SFG_StrokeVertex ch91st0[] =
+{
+ {35.7143,119.048},
+ {35.7143,-33.3333}
+};
+
+static const SFG_StrokeVertex ch91st1[] =
+{
+ {40.4762,119.048},
+ {40.4762,-33.3333}
+};
+
+static const SFG_StrokeVertex ch91st2[] =
+{
+ {35.7143,119.048},
+ {69.0476,119.048}
+};
+
+static const SFG_StrokeVertex ch91st3[] =
+{
+ {35.7143,-33.3333},
+ {69.0476,-33.3333}
+};
+
+static const SFG_StrokeStrip ch91st[] =
+{
+ {2,ch91st0},
+ {2,ch91st1},
+ {2,ch91st2},
+ {2,ch91st3}
+};
+
+static const SFG_StrokeChar ch91 = {104.762,4,ch91st};
+
+/* char: 0x5c */
+
+static const SFG_StrokeVertex ch92st0[] =
+{
+ {19.0476,100},
+ {85.7143,-14.2857}
+};
+
+static const SFG_StrokeStrip ch92st[] =
+{
+ {2,ch92st0}
+};
+
+static const SFG_StrokeChar ch92 = {104.762,1,ch92st};
+
+/* char: 0x5d */
+
+static const SFG_StrokeVertex ch93st0[] =
+{
+ {64.2857,119.048},
+ {64.2857,-33.3333}
+};
+
+static const SFG_StrokeVertex ch93st1[] =
+{
+ {69.0476,119.048},
+ {69.0476,-33.3333}
+};
+
+static const SFG_StrokeVertex ch93st2[] =
+{
+ {35.7143,119.048},
+ {69.0476,119.048}
+};
+
+static const SFG_StrokeVertex ch93st3[] =
+{
+ {35.7143,-33.3333},
+ {69.0476,-33.3333}
+};
+
+static const SFG_StrokeStrip ch93st[] =
+{
+ {2,ch93st0},
+ {2,ch93st1},
+ {2,ch93st2},
+ {2,ch93st3}
+};
+
+static const SFG_StrokeChar ch93 = {104.762,4,ch93st};
+
+/* char: 0x5e */
+
+static const SFG_StrokeVertex ch94st0[] =
+{
+ {52.3809,109.524},
+ {14.2857,42.8571}
+};
+
+static const SFG_StrokeVertex ch94st1[] =
+{
+ {52.3809,109.524},
+ {90.4762,42.8571}
+};
+
+static const SFG_StrokeStrip ch94st[] =
+{
+ {2,ch94st0},
+ {2,ch94st1}
+};
+
+static const SFG_StrokeChar ch94 = {104.762,2,ch94st};
+
+/* char: 0x5f */
+
+static const SFG_StrokeVertex ch95st0[] =
+{
+ {0,-33.3333},
+ {104.762,-33.3333},
+ {104.762,-28.5714},
+ {0,-28.5714},
+ {0,-33.3333}
+};
+
+static const SFG_StrokeStrip ch95st[] =
+{
+ {5,ch95st0}
+};
+
+static const SFG_StrokeChar ch95 = {104.762,1,ch95st};
+
+/* char: 0x60 */
+
+static const SFG_StrokeVertex ch96st0[] =
+{
+ {42.8572,100},
+ {66.6667,71.4286}
+};
+
+static const SFG_StrokeVertex ch96st1[] =
+{
+ {42.8572,100},
+ {38.0953,95.2381},
+ {66.6667,71.4286}
+};
+
+static const SFG_StrokeStrip ch96st[] =
+{
+ {2,ch96st0},
+ {3,ch96st1}
+};
+
+static const SFG_StrokeChar ch96 = {104.762,2,ch96st};
+
+/* char: 0x61 */
+
+static const SFG_StrokeVertex ch97st0[] =
+{
+ {80.9524,66.6667},
+ {80.9524,0}
+};
+
+static const SFG_StrokeVertex ch97st1[] =
+{
+ {80.9524,52.381},
+ {71.4285,61.9048},
+ {61.9047,66.6667},
+ {47.619,66.6667},
+ {38.0952,61.9048},
+ {28.5714,52.381},
+ {23.8095,38.0952},
+ {23.8095,28.5714},
+ {28.5714,14.2857},
+ {38.0952,4.7619},
+ {47.619,0},
+ {61.9047,0},
+ {71.4285,4.7619},
+ {80.9524,14.2857}
+};
+
+static const SFG_StrokeStrip ch97st[] =
+{
+ {2,ch97st0},
+ {14,ch97st1}
+};
+
+static const SFG_StrokeChar ch97 = {104.762,2,ch97st};
+
+/* char: 0x62 */
+
+static const SFG_StrokeVertex ch98st0[] =
+{
+ {23.8095,100},
+ {23.8095,0}
+};
+
+static const SFG_StrokeVertex ch98st1[] =
+{
+ {23.8095,52.381},
+ {33.3333,61.9048},
+ {42.8571,66.6667},
+ {57.1428,66.6667},
+ {66.6666,61.9048},
+ {76.1905,52.381},
+ {80.9524,38.0952},
+ {80.9524,28.5714},
+ {76.1905,14.2857},
+ {66.6666,4.7619},
+ {57.1428,0},
+ {42.8571,0},
+ {33.3333,4.7619},
+ {23.8095,14.2857}
+};
+
+static const SFG_StrokeStrip ch98st[] =
+{
+ {2,ch98st0},
+ {14,ch98st1}
+};
+
+static const SFG_StrokeChar ch98 = {104.762,2,ch98st};
+
+/* char: 0x63 */
+
+static const SFG_StrokeVertex ch99st0[] =
+{
+ {80.9524,52.381},
+ {71.4285,61.9048},
+ {61.9047,66.6667},
+ {47.619,66.6667},
+ {38.0952,61.9048},
+ {28.5714,52.381},
+ {23.8095,38.0952},
+ {23.8095,28.5714},
+ {28.5714,14.2857},
+ {38.0952,4.7619},
+ {47.619,0},
+ {61.9047,0},
+ {71.4285,4.7619},
+ {80.9524,14.2857}
+};
+
+static const SFG_StrokeStrip ch99st[] =
+{
+ {14,ch99st0}
+};
+
+static const SFG_StrokeChar ch99 = {104.762,1,ch99st};
+
+/* char: 0x64 */
+
+static const SFG_StrokeVertex ch100st0[] =
+{
+ {80.9524,100},
+ {80.9524,0}
+};
+
+static const SFG_StrokeVertex ch100st1[] =
+{
+ {80.9524,52.381},
+ {71.4285,61.9048},
+ {61.9047,66.6667},
+ {47.619,66.6667},
+ {38.0952,61.9048},
+ {28.5714,52.381},
+ {23.8095,38.0952},
+ {23.8095,28.5714},
+ {28.5714,14.2857},
+ {38.0952,4.7619},
+ {47.619,0},
+ {61.9047,0},
+ {71.4285,4.7619},
+ {80.9524,14.2857}
+};
+
+static const SFG_StrokeStrip ch100st[] =
+{
+ {2,ch100st0},
+ {14,ch100st1}
+};
+
+static const SFG_StrokeChar ch100 = {104.762,2,ch100st};
+
+/* char: 0x65 */
+
+static const SFG_StrokeVertex ch101st0[] =
+{
+ {23.8095,38.0952},
+ {80.9524,38.0952},
+ {80.9524,47.619},
+ {76.1905,57.1429},
+ {71.4285,61.9048},
+ {61.9047,66.6667},
+ {47.619,66.6667},
+ {38.0952,61.9048},
+ {28.5714,52.381},
+ {23.8095,38.0952},
+ {23.8095,28.5714},
+ {28.5714,14.2857},
+ {38.0952,4.7619},
+ {47.619,0},
+ {61.9047,0},
+ {71.4285,4.7619},
+ {80.9524,14.2857}
+};
+
+static const SFG_StrokeStrip ch101st[] =
+{
+ {17,ch101st0}
+};
+
+static const SFG_StrokeChar ch101 = {104.762,1,ch101st};
+
+/* char: 0x66 */
+
+static const SFG_StrokeVertex ch102st0[] =
+{
+ {71.4286,100},
+ {61.9048,100},
+ {52.381,95.2381},
+ {47.6191,80.9524},
+ {47.6191,0}
+};
+
+static const SFG_StrokeVertex ch102st1[] =
+{
+ {33.3334,66.6667},
+ {66.6667,66.6667}
+};
+
+static const SFG_StrokeStrip ch102st[] =
+{
+ {5,ch102st0},
+ {2,ch102st1}
+};
+
+static const SFG_StrokeChar ch102 = {104.762,2,ch102st};
+
+/* char: 0x67 */
+
+static const SFG_StrokeVertex ch103st0[] =
+{
+ {80.9524,66.6667},
+ {80.9524,-9.5238},
+ {76.1905,-23.8095},
+ {71.4285,-28.5714},
+ {61.9047,-33.3333},
+ {47.619,-33.3333},
+ {38.0952,-28.5714}
+};
+
+static const SFG_StrokeVertex ch103st1[] =
+{
+ {80.9524,52.381},
+ {71.4285,61.9048},
+ {61.9047,66.6667},
+ {47.619,66.6667},
+ {38.0952,61.9048},
+ {28.5714,52.381},
+ {23.8095,38.0952},
+ {23.8095,28.5714},
+ {28.5714,14.2857},
+ {38.0952,4.7619},
+ {47.619,0},
+ {61.9047,0},
+ {71.4285,4.7619},
+ {80.9524,14.2857}
+};
+
+static const SFG_StrokeStrip ch103st[] =
+{
+ {7,ch103st0},
+ {14,ch103st1}
+};
+
+static const SFG_StrokeChar ch103 = {104.762,2,ch103st};
+
+/* char: 0x68 */
+
+static const SFG_StrokeVertex ch104st0[] =
+{
+ {26.1905,100},
+ {26.1905,0}
+};
+
+static const SFG_StrokeVertex ch104st1[] =
+{
+ {26.1905,47.619},
+ {40.4762,61.9048},
+ {50,66.6667},
+ {64.2857,66.6667},
+ {73.8095,61.9048},
+ {78.5715,47.619},
+ {78.5715,0}
+};
+
+static const SFG_StrokeStrip ch104st[] =
+{
+ {2,ch104st0},
+ {7,ch104st1}
+};
+
+static const SFG_StrokeChar ch104 = {104.762,2,ch104st};
+
+/* char: 0x69 */
+
+static const SFG_StrokeVertex ch105st0[] =
+{
+ {47.6191,100},
+ {52.381,95.2381},
+ {57.1429,100},
+ {52.381,104.762},
+ {47.6191,100}
+};
+
+static const SFG_StrokeVertex ch105st1[] =
+{
+ {52.381,66.6667},
+ {52.381,0}
+};
+
+static const SFG_StrokeStrip ch105st[] =
+{
+ {5,ch105st0},
+ {2,ch105st1}
+};
+
+static const SFG_StrokeChar ch105 = {104.762,2,ch105st};
+
+/* char: 0x6a */
+
+static const SFG_StrokeVertex ch106st0[] =
+{
+ {57.1429,100},
+ {61.9048,95.2381},
+ {66.6667,100},
+ {61.9048,104.762},
+ {57.1429,100}
+};
+
+static const SFG_StrokeVertex ch106st1[] =
+{
+ {61.9048,66.6667},
+ {61.9048,-14.2857},
+ {57.1429,-28.5714},
+ {47.6191,-33.3333},
+ {38.0953,-33.3333}
+};
+
+static const SFG_StrokeStrip ch106st[] =
+{
+ {5,ch106st0},
+ {5,ch106st1}
+};
+
+static const SFG_StrokeChar ch106 = {104.762,2,ch106st};
+
+/* char: 0x6b */
+
+static const SFG_StrokeVertex ch107st0[] =
+{
+ {26.1905,100},
+ {26.1905,0}
+};
+
+static const SFG_StrokeVertex ch107st1[] =
+{
+ {73.8095,66.6667},
+ {26.1905,19.0476}
+};
+
+static const SFG_StrokeVertex ch107st2[] =
+{
+ {45.2381,38.0952},
+ {78.5715,0}
+};
+
+static const SFG_StrokeStrip ch107st[] =
+{
+ {2,ch107st0},
+ {2,ch107st1},
+ {2,ch107st2}
+};
+
+static const SFG_StrokeChar ch107 = {104.762,3,ch107st};
+
+/* char: 0x6c */
+
+static const SFG_StrokeVertex ch108st0[] =
+{
+ {52.381,100},
+ {52.381,0}
+};
+
+static const SFG_StrokeStrip ch108st[] =
+{
+ {2,ch108st0}
+};
+
+static const SFG_StrokeChar ch108 = {104.762,1,ch108st};
+
+/* char: 0x6d */
+
+static const SFG_StrokeVertex ch109st0[] =
+{
+ {0,66.6667},
+ {0,0}
+};
+
+static const SFG_StrokeVertex ch109st1[] =
+{
+ {0,47.619},
+ {14.2857,61.9048},
+ {23.8095,66.6667},
+ {38.0952,66.6667},
+ {47.619,61.9048},
+ {52.381,47.619},
+ {52.381,0}
+};
+
+static const SFG_StrokeVertex ch109st2[] =
+{
+ {52.381,47.619},
+ {66.6667,61.9048},
+ {76.1905,66.6667},
+ {90.4762,66.6667},
+ {100,61.9048},
+ {104.762,47.619},
+ {104.762,0}
+};
+
+static const SFG_StrokeStrip ch109st[] =
+{
+ {2,ch109st0},
+ {7,ch109st1},
+ {7,ch109st2}
+};
+
+static const SFG_StrokeChar ch109 = {104.762,3,ch109st};
+
+/* char: 0x6e */
+
+static const SFG_StrokeVertex ch110st0[] =
+{
+ {26.1905,66.6667},
+ {26.1905,0}
+};
+
+static const SFG_StrokeVertex ch110st1[] =
+{
+ {26.1905,47.619},
+ {40.4762,61.9048},
+ {50,66.6667},
+ {64.2857,66.6667},
+ {73.8095,61.9048},
+ {78.5715,47.619},
+ {78.5715,0}
+};
+
+static const SFG_StrokeStrip ch110st[] =
+{
+ {2,ch110st0},
+ {7,ch110st1}
+};
+
+static const SFG_StrokeChar ch110 = {104.762,2,ch110st};
+
+/* char: 0x6f */
+
+static const SFG_StrokeVertex ch111st0[] =
+{
+ {45.2381,66.6667},
+ {35.7143,61.9048},
+ {26.1905,52.381},
+ {21.4286,38.0952},
+ {21.4286,28.5714},
+ {26.1905,14.2857},
+ {35.7143,4.7619},
+ {45.2381,0},
+ {59.5238,0},
+ {69.0476,4.7619},
+ {78.5714,14.2857},
+ {83.3334,28.5714},
+ {83.3334,38.0952},
+ {78.5714,52.381},
+ {69.0476,61.9048},
+ {59.5238,66.6667},
+ {45.2381,66.6667}
+};
+
+static const SFG_StrokeStrip ch111st[] =
+{
+ {17,ch111st0}
+};
+
+static const SFG_StrokeChar ch111 = {104.762,1,ch111st};
+
+/* char: 0x70 */
+
+static const SFG_StrokeVertex ch112st0[] =
+{
+ {23.8095,66.6667},
+ {23.8095,-33.3333}
+};
+
+static const SFG_StrokeVertex ch112st1[] =
+{
+ {23.8095,52.381},
+ {33.3333,61.9048},
+ {42.8571,66.6667},
+ {57.1428,66.6667},
+ {66.6666,61.9048},
+ {76.1905,52.381},
+ {80.9524,38.0952},
+ {80.9524,28.5714},
+ {76.1905,14.2857},
+ {66.6666,4.7619},
+ {57.1428,0},
+ {42.8571,0},
+ {33.3333,4.7619},
+ {23.8095,14.2857}
+};
+
+static const SFG_StrokeStrip ch112st[] =
+{
+ {2,ch112st0},
+ {14,ch112st1}
+};
+
+static const SFG_StrokeChar ch112 = {104.762,2,ch112st};
+
+/* char: 0x71 */
+
+static const SFG_StrokeVertex ch113st0[] =
+{
+ {80.9524,66.6667},
+ {80.9524,-33.3333}
+};
+
+static const SFG_StrokeVertex ch113st1[] =
+{
+ {80.9524,52.381},
+ {71.4285,61.9048},
+ {61.9047,66.6667},
+ {47.619,66.6667},
+ {38.0952,61.9048},
+ {28.5714,52.381},
+ {23.8095,38.0952},
+ {23.8095,28.5714},
+ {28.5714,14.2857},
+ {38.0952,4.7619},
+ {47.619,0},
+ {61.9047,0},
+ {71.4285,4.7619},
+ {80.9524,14.2857}
+};
+
+static const SFG_StrokeStrip ch113st[] =
+{
+ {2,ch113st0},
+ {14,ch113st1}
+};
+
+static const SFG_StrokeChar ch113 = {104.762,2,ch113st};
+
+/* char: 0x72 */
+
+static const SFG_StrokeVertex ch114st0[] =
+{
+ {33.3334,66.6667},
+ {33.3334,0}
+};
+
+static const SFG_StrokeVertex ch114st1[] =
+{
+ {33.3334,38.0952},
+ {38.0953,52.381},
+ {47.6191,61.9048},
+ {57.1429,66.6667},
+ {71.4286,66.6667}
+};
+
+static const SFG_StrokeStrip ch114st[] =
+{
+ {2,ch114st0},
+ {5,ch114st1}
+};
+
+static const SFG_StrokeChar ch114 = {104.762,2,ch114st};
+
+/* char: 0x73 */
+
+static const SFG_StrokeVertex ch115st0[] =
+{
+ {78.5715,52.381},
+ {73.8095,61.9048},
+ {59.5238,66.6667},
+ {45.2381,66.6667},
+ {30.9524,61.9048},
+ {26.1905,52.381},
+ {30.9524,42.8571},
+ {40.4762,38.0952},
+ {64.2857,33.3333},
+ {73.8095,28.5714},
+ {78.5715,19.0476},
+ {78.5715,14.2857},
+ {73.8095,4.7619},
+ {59.5238,0},
+ {45.2381,0},
+ {30.9524,4.7619},
+ {26.1905,14.2857}
+};
+
+static const SFG_StrokeStrip ch115st[] =
+{
+ {17,ch115st0}
+};
+
+static const SFG_StrokeChar ch115 = {104.762,1,ch115st};
+
+/* char: 0x74 */
+
+static const SFG_StrokeVertex ch116st0[] =
+{
+ {47.6191,100},
+ {47.6191,19.0476},
+ {52.381,4.7619},
+ {61.9048,0},
+ {71.4286,0}
+};
+
+static const SFG_StrokeVertex ch116st1[] =
+{
+ {33.3334,66.6667},
+ {66.6667,66.6667}
+};
+
+static const SFG_StrokeStrip ch116st[] =
+{
+ {5,ch116st0},
+ {2,ch116st1}
+};
+
+static const SFG_StrokeChar ch116 = {104.762,2,ch116st};
+
+/* char: 0x75 */
+
+static const SFG_StrokeVertex ch117st0[] =
+{
+ {26.1905,66.6667},
+ {26.1905,19.0476},
+ {30.9524,4.7619},
+ {40.4762,0},
+ {54.7619,0},
+ {64.2857,4.7619},
+ {78.5715,19.0476}
+};
+
+static const SFG_StrokeVertex ch117st1[] =
+{
+ {78.5715,66.6667},
+ {78.5715,0}
+};
+
+static const SFG_StrokeStrip ch117st[] =
+{
+ {7,ch117st0},
+ {2,ch117st1}
+};
+
+static const SFG_StrokeChar ch117 = {104.762,2,ch117st};
+
+/* char: 0x76 */
+
+static const SFG_StrokeVertex ch118st0[] =
+{
+ {23.8095,66.6667},
+ {52.3809,0}
+};
+
+static const SFG_StrokeVertex ch118st1[] =
+{
+ {80.9524,66.6667},
+ {52.3809,0}
+};
+
+static const SFG_StrokeStrip ch118st[] =
+{
+ {2,ch118st0},
+ {2,ch118st1}
+};
+
+static const SFG_StrokeChar ch118 = {104.762,2,ch118st};
+
+/* char: 0x77 */
+
+static const SFG_StrokeVertex ch119st0[] =
+{
+ {14.2857,66.6667},
+ {33.3333,0}
+};
+
+static const SFG_StrokeVertex ch119st1[] =
+{
+ {52.3809,66.6667},
+ {33.3333,0}
+};
+
+static const SFG_StrokeVertex ch119st2[] =
+{
+ {52.3809,66.6667},
+ {71.4286,0}
+};
+
+static const SFG_StrokeVertex ch119st3[] =
+{
+ {90.4762,66.6667},
+ {71.4286,0}
+};
+
+static const SFG_StrokeStrip ch119st[] =
+{
+ {2,ch119st0},
+ {2,ch119st1},
+ {2,ch119st2},
+ {2,ch119st3}
+};
+
+static const SFG_StrokeChar ch119 = {104.762,4,ch119st};
+
+/* char: 0x78 */
+
+static const SFG_StrokeVertex ch120st0[] =
+{
+ {26.1905,66.6667},
+ {78.5715,0}
+};
+
+static const SFG_StrokeVertex ch120st1[] =
+{
+ {78.5715,66.6667},
+ {26.1905,0}
+};
+
+static const SFG_StrokeStrip ch120st[] =
+{
+ {2,ch120st0},
+ {2,ch120st1}
+};
+
+static const SFG_StrokeChar ch120 = {104.762,2,ch120st};
+
+/* char: 0x79 */
+
+static const SFG_StrokeVertex ch121st0[] =
+{
+ {26.1905,66.6667},
+ {54.7619,0}
+};
+
+static const SFG_StrokeVertex ch121st1[] =
+{
+ {83.3334,66.6667},
+ {54.7619,0},
+ {45.2381,-19.0476},
+ {35.7143,-28.5714},
+ {26.1905,-33.3333},
+ {21.4286,-33.3333}
+};
+
+static const SFG_StrokeStrip ch121st[] =
+{
+ {2,ch121st0},
+ {6,ch121st1}
+};
+
+static const SFG_StrokeChar ch121 = {104.762,2,ch121st};
+
+/* char: 0x7a */
+
+static const SFG_StrokeVertex ch122st0[] =
+{
+ {78.5715,66.6667},
+ {26.1905,0}
+};
+
+static const SFG_StrokeVertex ch122st1[] =
+{
+ {26.1905,66.6667},
+ {78.5715,66.6667}
+};
+
+static const SFG_StrokeVertex ch122st2[] =
+{
+ {26.1905,0},
+ {78.5715,0}
+};
+
+static const SFG_StrokeStrip ch122st[] =
+{
+ {2,ch122st0},
+ {2,ch122st1},
+ {2,ch122st2}
+};
+
+static const SFG_StrokeChar ch122 = {104.762,3,ch122st};
+
+/* char: 0x7b */
+
+static const SFG_StrokeVertex ch123st0[] =
+{
+ {64.2857,119.048},
+ {54.7619,114.286},
+ {50,109.524},
+ {45.2381,100},
+ {45.2381,90.4762},
+ {50,80.9524},
+ {54.7619,76.1905},
+ {59.5238,66.6667},
+ {59.5238,57.1429},
+ {50,47.619}
+};
+
+static const SFG_StrokeVertex ch123st1[] =
+{
+ {54.7619,114.286},
+ {50,104.762},
+ {50,95.2381},
+ {54.7619,85.7143},
+ {59.5238,80.9524},
+ {64.2857,71.4286},
+ {64.2857,61.9048},
+ {59.5238,52.381},
+ {40.4762,42.8571},
+ {59.5238,33.3333},
+ {64.2857,23.8095},
+ {64.2857,14.2857},
+ {59.5238,4.7619},
+ {54.7619,0},
+ {50,-9.5238},
+ {50,-19.0476},
+ {54.7619,-28.5714}
+};
+
+static const SFG_StrokeVertex ch123st2[] =
+{
+ {50,38.0952},
+ {59.5238,28.5714},
+ {59.5238,19.0476},
+ {54.7619,9.5238},
+ {50,4.7619},
+ {45.2381,-4.7619},
+ {45.2381,-14.2857},
+ {50,-23.8095},
+ {54.7619,-28.5714},
+ {64.2857,-33.3333}
+};
+
+static const SFG_StrokeStrip ch123st[] =
+{
+ {10,ch123st0},
+ {17,ch123st1},
+ {10,ch123st2}
+};
+
+static const SFG_StrokeChar ch123 = {104.762,3,ch123st};
+
+/* char: 0x7c */
+
+static const SFG_StrokeVertex ch124st0[] =
+{
+ {52.381,119.048},
+ {52.381,-33.3333}
+};
+
+static const SFG_StrokeStrip ch124st[] =
+{
+ {2,ch124st0}
+};
+
+static const SFG_StrokeChar ch124 = {104.762,1,ch124st};
+
+/* char: 0x7d */
+
+static const SFG_StrokeVertex ch125st0[] =
+{
+ {40.4762,119.048},
+ {50,114.286},
+ {54.7619,109.524},
+ {59.5238,100},
+ {59.5238,90.4762},
+ {54.7619,80.9524},
+ {50,76.1905},
+ {45.2381,66.6667},
+ {45.2381,57.1429},
+ {54.7619,47.619}
+};
+
+static const SFG_StrokeVertex ch125st1[] =
+{
+ {50,114.286},
+ {54.7619,104.762},
+ {54.7619,95.2381},
+ {50,85.7143},
+ {45.2381,80.9524},
+ {40.4762,71.4286},
+ {40.4762,61.9048},
+ {45.2381,52.381},
+ {64.2857,42.8571},
+ {45.2381,33.3333},
+ {40.4762,23.8095},
+ {40.4762,14.2857},
+ {45.2381,4.7619},
+ {50,0},
+ {54.7619,-9.5238},
+ {54.7619,-19.0476},
+ {50,-28.5714}
+};
+
+static const SFG_StrokeVertex ch125st2[] =
+{
+ {54.7619,38.0952},
+ {45.2381,28.5714},
+ {45.2381,19.0476},
+ {50,9.5238},
+ {54.7619,4.7619},
+ {59.5238,-4.7619},
+ {59.5238,-14.2857},
+ {54.7619,-23.8095},
+ {50,-28.5714},
+ {40.4762,-33.3333}
+};
+
+static const SFG_StrokeStrip ch125st[] =
+{
+ {10,ch125st0},
+ {17,ch125st1},
+ {10,ch125st2}
+};
+
+static const SFG_StrokeChar ch125 = {104.762,3,ch125st};
+
+/* char: 0x7e */
+
+static const SFG_StrokeVertex ch126st0[] =
+{
+ {9.5238,28.5714},
+ {9.5238,38.0952},
+ {14.2857,52.381},
+ {23.8095,57.1429},
+ {33.3333,57.1429},
+ {42.8571,52.381},
+ {61.9048,38.0952},
+ {71.4286,33.3333},
+ {80.9524,33.3333},
+ {90.4762,38.0952},
+ {95.2381,47.619}
+};
+
+static const SFG_StrokeVertex ch126st1[] =
+{
+ {9.5238,38.0952},
+ {14.2857,47.619},
+ {23.8095,52.381},
+ {33.3333,52.381},
+ {42.8571,47.619},
+ {61.9048,33.3333},
+ {71.4286,28.5714},
+ {80.9524,28.5714},
+ {90.4762,33.3333},
+ {95.2381,47.619},
+ {95.2381,57.1429}
+};
+
+static const SFG_StrokeStrip ch126st[] =
+{
+ {11,ch126st0},
+ {11,ch126st1}
+};
+
+static const SFG_StrokeChar ch126 = {104.762,2,ch126st};
+
+/* char: 0x7f */
+
+static const SFG_StrokeVertex ch127st0[] =
+{
+ {71.4286,100},
+ {33.3333,-33.3333}
+};
+
+static const SFG_StrokeVertex ch127st1[] =
+{
+ {47.619,66.6667},
+ {33.3333,61.9048},
+ {23.8095,52.381},
+ {19.0476,38.0952},
+ {19.0476,23.8095},
+ {23.8095,14.2857},
+ {33.3333,4.7619},
+ {47.619,0},
+ {57.1428,0},
+ {71.4286,4.7619},
+ {80.9524,14.2857},
+ {85.7143,28.5714},
+ {85.7143,42.8571},
+ {80.9524,52.381},
+ {71.4286,61.9048},
+ {57.1428,66.6667},
+ {47.619,66.6667}
+};
+
+static const SFG_StrokeStrip ch127st[] =
+{
+ {2,ch127st0},
+ {17,ch127st1}
+};
+
+static const SFG_StrokeChar ch127 = {104.762,2,ch127st};
+
+static const SFG_StrokeChar *chars[] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ &ch32, &ch33, &ch34, &ch35, &ch36, &ch37, &ch38, &ch39,
+ &ch40, &ch41, &ch42, &ch43, &ch44, &ch45, &ch46, &ch47,
+ &ch48, &ch49, &ch50, &ch51, &ch52, &ch53, &ch54, &ch55,
+ &ch56, &ch57, &ch58, &ch59, &ch60, &ch61, &ch62, &ch63,
+ &ch64, &ch65, &ch66, &ch67, &ch68, &ch69, &ch70, &ch71,
+ &ch72, &ch73, &ch74, &ch75, &ch76, &ch77, &ch78, &ch79,
+ &ch80, &ch81, &ch82, &ch83, &ch84, &ch85, &ch86, &ch87,
+ &ch88, &ch89, &ch90, &ch91, &ch92, &ch93, &ch94, &ch95,
+ &ch96, &ch97, &ch98, &ch99, &ch100, &ch101, &ch102, &ch103,
+ &ch104, &ch105, &ch106, &ch107, &ch108, &ch109, &ch110, &ch111,
+ &ch112, &ch113, &ch114, &ch115, &ch116, &ch117, &ch118, &ch119,
+ &ch120, &ch121, &ch122, &ch123, &ch124, &ch125, &ch126, &ch127
+};
+
+const SFG_StrokeFont fgStrokeMonoRoman = {"MonoRoman",128,152.381,chars};
diff --git a/src/freeglut_stroke_roman.c b/src/freeglut_stroke_roman.c
new file mode 100644 (file)
index 0000000..c7ecd2b
--- /dev/null
@@ -0,0 +1,2824 @@
+
+/* This file has been automatically generated by the genstroke utility. */
+
+#include "freeglut_internal.h"
+#ifdef TARGET_HOST_WIN32
+#pragma warning ( once:4305 )
+#endif
+
+/* char: 0x20 */
+
+static const SFG_StrokeStrip ch32st[] =
+{
+  { 0, NULL }
+};
+
+static const SFG_StrokeChar ch32 = {104.762,0,ch32st};
+
+/* char: 0x21 */
+
+static const SFG_StrokeVertex ch33st0[] =
+{
+ {13.3819,100},
+ {13.3819,33.3333}
+};
+
+static const SFG_StrokeVertex ch33st1[] =
+{
+ {13.3819,9.5238},
+ {8.62,4.7619},
+ {13.3819,0},
+ {18.1438,4.7619},
+ {13.3819,9.5238}
+};
+
+static const SFG_StrokeStrip ch33st[] =
+{
+ {2,ch33st0},
+ {5,ch33st1}
+};
+
+static const SFG_StrokeChar ch33 = {26.6238,2,ch33st};
+
+/* char: 0x22 */
+
+static const SFG_StrokeVertex ch34st0[] =
+{
+ {4.02,100},
+ {4.02,66.6667}
+};
+
+static const SFG_StrokeVertex ch34st1[] =
+{
+ {42.1152,100},
+ {42.1152,66.6667}
+};
+
+static const SFG_StrokeStrip ch34st[] =
+{
+ {2,ch34st0},
+ {2,ch34st1}
+};
+
+static const SFG_StrokeChar ch34 = {51.4352,2,ch34st};
+
+/* char: 0x23 */
+
+static const SFG_StrokeVertex ch35st0[] =
+{
+ {41.2952,119.048},
+ {7.9619,-33.3333}
+};
+
+static const SFG_StrokeVertex ch35st1[] =
+{
+ {69.8667,119.048},
+ {36.5333,-33.3333}
+};
+
+static const SFG_StrokeVertex ch35st2[] =
+{
+ {7.9619,57.1429},
+ {74.6286,57.1429}
+};
+
+static const SFG_StrokeVertex ch35st3[] =
+{
+ {3.2,28.5714},
+ {69.8667,28.5714}
+};
+
+static const SFG_StrokeStrip ch35st[] =
+{
+ {2,ch35st0},
+ {2,ch35st1},
+ {2,ch35st2},
+ {2,ch35st3}
+};
+
+static const SFG_StrokeChar ch35 = {79.4886,4,ch35st};
+
+/* char: 0x24 */
+
+static const SFG_StrokeVertex ch36st0[] =
+{
+ {28.6295,119.048},
+ {28.6295,-19.0476}
+};
+
+static const SFG_StrokeVertex ch36st1[] =
+{
+ {47.6771,119.048},
+ {47.6771,-19.0476}
+};
+
+static const SFG_StrokeVertex ch36st2[] =
+{
+ {71.4867,85.7143},
+ {61.9629,95.2381},
+ {47.6771,100},
+ {28.6295,100},
+ {14.3438,95.2381},
+ {4.82,85.7143},
+ {4.82,76.1905},
+ {9.5819,66.6667},
+ {14.3438,61.9048},
+ {23.8676,57.1429},
+ {52.439,47.619},
+ {61.9629,42.8571},
+ {66.7248,38.0952},
+ {71.4867,28.5714},
+ {71.4867,14.2857},
+ {61.9629,4.7619},
+ {47.6771,0},
+ {28.6295,0},
+ {14.3438,4.7619},
+ {4.82,14.2857}
+};
+
+static const SFG_StrokeStrip ch36st[] =
+{
+ {2,ch36st0},
+ {2,ch36st1},
+ {20,ch36st2}
+};
+
+static const SFG_StrokeChar ch36 = {76.2067,3,ch36st};
+
+/* char: 0x25 */
+
+static const SFG_StrokeVertex ch37st0[] =
+{
+ {92.0743,100},
+ {6.36,0}
+};
+
+static const SFG_StrokeVertex ch37st1[] =
+{
+ {30.1695,100},
+ {39.6933,90.4762},
+ {39.6933,80.9524},
+ {34.9314,71.4286},
+ {25.4076,66.6667},
+ {15.8838,66.6667},
+ {6.36,76.1905},
+ {6.36,85.7143},
+ {11.1219,95.2381},
+ {20.6457,100},
+ {30.1695,100},
+ {39.6933,95.2381},
+ {53.979,90.4762},
+ {68.2648,90.4762},
+ {82.5505,95.2381},
+ {92.0743,100}
+};
+
+static const SFG_StrokeVertex ch37st2[] =
+{
+ {73.0267,33.3333},
+ {63.5029,28.5714},
+ {58.741,19.0476},
+ {58.741,9.5238},
+ {68.2648,0},
+ {77.7886,0},
+ {87.3124,4.7619},
+ {92.0743,14.2857},
+ {92.0743,23.8095},
+ {82.5505,33.3333},
+ {73.0267,33.3333}
+};
+
+static const SFG_StrokeStrip ch37st[] =
+{
+ {2,ch37st0},
+ {16,ch37st1},
+ {11,ch37st2}
+};
+
+static const SFG_StrokeChar ch37 = {96.5743,3,ch37st};
+
+/* char: 0x26 */
+
+static const SFG_StrokeVertex ch38st0[] =
+{
+ {101.218,57.1429},
+ {101.218,61.9048},
+ {96.4562,66.6667},
+ {91.6943,66.6667},
+ {86.9324,61.9048},
+ {82.1705,52.381},
+ {72.6467,28.5714},
+ {63.1229,14.2857},
+ {53.599,4.7619},
+ {44.0752,0},
+ {25.0276,0},
+ {15.5038,4.7619},
+ {10.7419,9.5238},
+ {5.98,19.0476},
+ {5.98,28.5714},
+ {10.7419,38.0952},
+ {15.5038,42.8571},
+ {48.8371,61.9048},
+ {53.599,66.6667},
+ {58.361,76.1905},
+ {58.361,85.7143},
+ {53.599,95.2381},
+ {44.0752,100},
+ {34.5514,95.2381},
+ {29.7895,85.7143},
+ {29.7895,76.1905},
+ {34.5514,61.9048},
+ {44.0752,47.619},
+ {67.8848,14.2857},
+ {77.4086,4.7619},
+ {86.9324,0},
+ {96.4562,0},
+ {101.218,4.7619},
+ {101.218,9.5238}
+};
+
+static const SFG_StrokeStrip ch38st[] =
+{
+ {34,ch38st0}
+};
+
+static const SFG_StrokeChar ch38 = {101.758,1,ch38st};
+
+/* char: 0x27 */
+
+static const SFG_StrokeVertex ch39st0[] =
+{
+ {4.44,100},
+ {4.44,66.6667}
+};
+
+static const SFG_StrokeStrip ch39st[] =
+{
+ {2,ch39st0}
+};
+
+static const SFG_StrokeChar ch39 = {13.62,1,ch39st};
+
+/* char: 0x28 */
+
+static const SFG_StrokeVertex ch40st0[] =
+{
+ {40.9133,119.048},
+ {31.3895,109.524},
+ {21.8657,95.2381},
+ {12.3419,76.1905},
+ {7.58,52.381},
+ {7.58,33.3333},
+ {12.3419,9.5238},
+ {21.8657,-9.5238},
+ {31.3895,-23.8095},
+ {40.9133,-33.3333}
+};
+
+static const SFG_StrokeStrip ch40st[] =
+{
+ {10,ch40st0}
+};
+
+static const SFG_StrokeChar ch40 = {47.1733,1,ch40st};
+
+/* char: 0x29 */
+
+static const SFG_StrokeVertex ch41st0[] =
+{
+ {5.28,119.048},
+ {14.8038,109.524},
+ {24.3276,95.2381},
+ {33.8514,76.1905},
+ {38.6133,52.381},
+ {38.6133,33.3333},
+ {33.8514,9.5238},
+ {24.3276,-9.5238},
+ {14.8038,-23.8095},
+ {5.28,-33.3333}
+};
+
+static const SFG_StrokeStrip ch41st[] =
+{
+ {10,ch41st0}
+};
+
+static const SFG_StrokeChar ch41 = {47.5333,1,ch41st};
+
+/* char: 0x2a */
+
+static const SFG_StrokeVertex ch42st0[] =
+{
+ {30.7695,71.4286},
+ {30.7695,14.2857}
+};
+
+static const SFG_StrokeVertex ch42st1[] =
+{
+ {6.96,57.1429},
+ {54.579,28.5714}
+};
+
+static const SFG_StrokeVertex ch42st2[] =
+{
+ {54.579,57.1429},
+ {6.96,28.5714}
+};
+
+static const SFG_StrokeStrip ch42st[] =
+{
+ {2,ch42st0},
+ {2,ch42st1},
+ {2,ch42st2}
+};
+
+static const SFG_StrokeChar ch42 = {59.439,3,ch42st};
+
+/* char: 0x2b */
+
+static const SFG_StrokeVertex ch43st0[] =
+{
+ {48.8371,85.7143},
+ {48.8371,0}
+};
+
+static const SFG_StrokeVertex ch43st1[] =
+{
+ {5.98,42.8571},
+ {91.6943,42.8571}
+};
+
+static const SFG_StrokeStrip ch43st[] =
+{
+ {2,ch43st0},
+ {2,ch43st1}
+};
+
+static const SFG_StrokeChar ch43 = {97.2543,2,ch43st};
+
+/* char: 0x2c */
+
+static const SFG_StrokeVertex ch44st0[] =
+{
+ {18.2838,4.7619},
+ {13.5219,0},
+ {8.76,4.7619},
+ {13.5219,9.5238},
+ {18.2838,4.7619},
+ {18.2838,-4.7619},
+ {13.5219,-14.2857},
+ {8.76,-19.0476}
+};
+
+static const SFG_StrokeStrip ch44st[] =
+{
+ {8,ch44st0}
+};
+
+static const SFG_StrokeChar ch44 = {26.0638,1,ch44st};
+
+/* char: 0x2d */
+
+static const SFG_StrokeVertex ch45st0[] =
+{
+ {7.38,42.8571},
+ {93.0943,42.8571}
+};
+
+static const SFG_StrokeStrip ch45st[] =
+{
+ {2,ch45st0}
+};
+
+static const SFG_StrokeChar ch45 = {100.754,1,ch45st};
+
+/* char: 0x2e */
+
+static const SFG_StrokeVertex ch46st0[] =
+{
+ {13.1019,9.5238},
+ {8.34,4.7619},
+ {13.1019,0},
+ {17.8638,4.7619},
+ {13.1019,9.5238}
+};
+
+static const SFG_StrokeStrip ch46st[] =
+{
+ {5,ch46st0}
+};
+
+static const SFG_StrokeChar ch46 = {26.4838,1,ch46st};
+
+/* char: 0x2f */
+
+static const SFG_StrokeVertex ch47st0[] =
+{
+ {7.24,-14.2857},
+ {73.9067,100}
+};
+
+static const SFG_StrokeStrip ch47st[] =
+{
+ {2,ch47st0}
+};
+
+static const SFG_StrokeChar ch47 = {82.1067,1,ch47st};
+
+/* char: 0x30 */
+
+static const SFG_StrokeVertex ch48st0[] =
+{
+ {33.5514,100},
+ {19.2657,95.2381},
+ {9.7419,80.9524},
+ {4.98,57.1429},
+ {4.98,42.8571},
+ {9.7419,19.0476},
+ {19.2657,4.7619},
+ {33.5514,0},
+ {43.0752,0},
+ {57.361,4.7619},
+ {66.8848,19.0476},
+ {71.6467,42.8571},
+ {71.6467,57.1429},
+ {66.8848,80.9524},
+ {57.361,95.2381},
+ {43.0752,100},
+ {33.5514,100}
+};
+
+static const SFG_StrokeStrip ch48st[] =
+{
+ {17,ch48st0}
+};
+
+static const SFG_StrokeChar ch48 = {77.0667,1,ch48st};
+
+/* char: 0x31 */
+
+static const SFG_StrokeVertex ch49st0[] =
+{
+ {11.82,80.9524},
+ {21.3438,85.7143},
+ {35.6295,100},
+ {35.6295,0}
+};
+
+static const SFG_StrokeStrip ch49st[] =
+{
+ {4,ch49st0}
+};
+
+static const SFG_StrokeChar ch49 = {66.5295,1,ch49st};
+
+/* char: 0x32 */
+
+static const SFG_StrokeVertex ch50st0[] =
+{
+ {10.1819,76.1905},
+ {10.1819,80.9524},
+ {14.9438,90.4762},
+ {19.7057,95.2381},
+ {29.2295,100},
+ {48.2771,100},
+ {57.801,95.2381},
+ {62.5629,90.4762},
+ {67.3248,80.9524},
+ {67.3248,71.4286},
+ {62.5629,61.9048},
+ {53.039,47.619},
+ {5.42,0},
+ {72.0867,0}
+};
+
+static const SFG_StrokeStrip ch50st[] =
+{
+ {14,ch50st0}
+};
+
+static const SFG_StrokeChar ch50 = {77.6467,1,ch50st};
+
+/* char: 0x33 */
+
+static const SFG_StrokeVertex ch51st0[] =
+{
+ {14.5238,100},
+ {66.9048,100},
+ {38.3333,61.9048},
+ {52.619,61.9048},
+ {62.1429,57.1429},
+ {66.9048,52.381},
+ {71.6667,38.0952},
+ {71.6667,28.5714},
+ {66.9048,14.2857},
+ {57.381,4.7619},
+ {43.0952,0},
+ {28.8095,0},
+ {14.5238,4.7619},
+ {9.7619,9.5238},
+ {5,19.0476}
+};
+
+static const SFG_StrokeStrip ch51st[] =
+{
+ {15,ch51st0}
+};
+
+static const SFG_StrokeChar ch51 = {77.0467,1,ch51st};
+
+/* char: 0x34 */
+
+static const SFG_StrokeVertex ch52st0[] =
+{
+ {51.499,100},
+ {3.88,33.3333},
+ {75.3086,33.3333}
+};
+
+static const SFG_StrokeVertex ch52st1[] =
+{
+ {51.499,100},
+ {51.499,0}
+};
+
+static const SFG_StrokeStrip ch52st[] =
+{
+ {3,ch52st0},
+ {2,ch52st1}
+};
+
+static const SFG_StrokeChar ch52 = {80.1686,2,ch52st};
+
+/* char: 0x35 */
+
+static const SFG_StrokeVertex ch53st0[] =
+{
+ {62.0029,100},
+ {14.3838,100},
+ {9.6219,57.1429},
+ {14.3838,61.9048},
+ {28.6695,66.6667},
+ {42.9552,66.6667},
+ {57.241,61.9048},
+ {66.7648,52.381},
+ {71.5267,38.0952},
+ {71.5267,28.5714},
+ {66.7648,14.2857},
+ {57.241,4.7619},
+ {42.9552,0},
+ {28.6695,0},
+ {14.3838,4.7619},
+ {9.6219,9.5238},
+ {4.86,19.0476}
+};
+
+static const SFG_StrokeStrip ch53st[] =
+{
+ {17,ch53st0}
+};
+
+static const SFG_StrokeChar ch53 = {77.6867,1,ch53st};
+
+/* char: 0x36 */
+
+static const SFG_StrokeVertex ch54st0[] =
+{
+ {62.7229,85.7143},
+ {57.961,95.2381},
+ {43.6752,100},
+ {34.1514,100},
+ {19.8657,95.2381},
+ {10.3419,80.9524},
+ {5.58,57.1429},
+ {5.58,33.3333},
+ {10.3419,14.2857},
+ {19.8657,4.7619},
+ {34.1514,0},
+ {38.9133,0},
+ {53.199,4.7619},
+ {62.7229,14.2857},
+ {67.4848,28.5714},
+ {67.4848,33.3333},
+ {62.7229,47.619},
+ {53.199,57.1429},
+ {38.9133,61.9048},
+ {34.1514,61.9048},
+ {19.8657,57.1429},
+ {10.3419,47.619},
+ {5.58,33.3333}
+};
+
+static const SFG_StrokeStrip ch54st[] =
+{
+ {23,ch54st0}
+};
+
+static const SFG_StrokeChar ch54 = {73.8048,1,ch54st};
+
+/* char: 0x37 */
+
+static const SFG_StrokeVertex ch55st0[] =
+{
+ {72.2267,100},
+ {24.6076,0}
+};
+
+static const SFG_StrokeVertex ch55st1[] =
+{
+ {5.56,100},
+ {72.2267,100}
+};
+
+static const SFG_StrokeStrip ch55st[] =
+{
+ {2,ch55st0},
+ {2,ch55st1}
+};
+
+static const SFG_StrokeChar ch55 = {77.2267,2,ch55st};
+
+/* char: 0x38 */
+
+static const SFG_StrokeVertex ch56st0[] =
+{
+ {29.4095,100},
+ {15.1238,95.2381},
+ {10.3619,85.7143},
+ {10.3619,76.1905},
+ {15.1238,66.6667},
+ {24.6476,61.9048},
+ {43.6952,57.1429},
+ {57.981,52.381},
+ {67.5048,42.8571},
+ {72.2667,33.3333},
+ {72.2667,19.0476},
+ {67.5048,9.5238},
+ {62.7429,4.7619},
+ {48.4571,0},
+ {29.4095,0},
+ {15.1238,4.7619},
+ {10.3619,9.5238},
+ {5.6,19.0476},
+ {5.6,33.3333},
+ {10.3619,42.8571},
+ {19.8857,52.381},
+ {34.1714,57.1429},
+ {53.219,61.9048},
+ {62.7429,66.6667},
+ {67.5048,76.1905},
+ {67.5048,85.7143},
+ {62.7429,95.2381},
+ {48.4571,100},
+ {29.4095,100}
+};
+
+static const SFG_StrokeStrip ch56st[] =
+{
+ {29,ch56st0}
+};
+
+static const SFG_StrokeChar ch56 = {77.6667,1,ch56st};
+
+/* char: 0x39 */
+
+static const SFG_StrokeVertex ch57st0[] =
+{
+ {68.5048,66.6667},
+ {63.7429,52.381},
+ {54.219,42.8571},
+ {39.9333,38.0952},
+ {35.1714,38.0952},
+ {20.8857,42.8571},
+ {11.3619,52.381},
+ {6.6,66.6667},
+ {6.6,71.4286},
+ {11.3619,85.7143},
+ {20.8857,95.2381},
+ {35.1714,100},
+ {39.9333,100},
+ {54.219,95.2381},
+ {63.7429,85.7143},
+ {68.5048,66.6667},
+ {68.5048,42.8571},
+ {63.7429,19.0476},
+ {54.219,4.7619},
+ {39.9333,0},
+ {30.4095,0},
+ {16.1238,4.7619},
+ {11.3619,14.2857}
+};
+
+static const SFG_StrokeStrip ch57st[] =
+{
+ {23,ch57st0}
+};
+
+static const SFG_StrokeChar ch57 = {74.0648,1,ch57st};
+
+/* char: 0x3a */
+
+static const SFG_StrokeVertex ch58st0[] =
+{
+ {14.0819,66.6667},
+ {9.32,61.9048},
+ {14.0819,57.1429},
+ {18.8438,61.9048},
+ {14.0819,66.6667}
+};
+
+static const SFG_StrokeVertex ch58st1[] =
+{
+ {14.0819,9.5238},
+ {9.32,4.7619},
+ {14.0819,0},
+ {18.8438,4.7619},
+ {14.0819,9.5238}
+};
+
+static const SFG_StrokeStrip ch58st[] =
+{
+ {5,ch58st0},
+ {5,ch58st1}
+};
+
+static const SFG_StrokeChar ch58 = {26.2238,2,ch58st};
+
+/* char: 0x3b */
+
+static const SFG_StrokeVertex ch59st0[] =
+{
+ {12.9619,66.6667},
+ {8.2,61.9048},
+ {12.9619,57.1429},
+ {17.7238,61.9048},
+ {12.9619,66.6667}
+};
+
+static const SFG_StrokeVertex ch59st1[] =
+{
+ {17.7238,4.7619},
+ {12.9619,0},
+ {8.2,4.7619},
+ {12.9619,9.5238},
+ {17.7238,4.7619},
+ {17.7238,-4.7619},
+ {12.9619,-14.2857},
+ {8.2,-19.0476}
+};
+
+static const SFG_StrokeStrip ch59st[] =
+{
+ {5,ch59st0},
+ {8,ch59st1}
+};
+
+static const SFG_StrokeChar ch59 = {26.3038,2,ch59st};
+
+/* char: 0x3c */
+
+static const SFG_StrokeVertex ch60st0[] =
+{
+ {79.2505,85.7143},
+ {3.06,42.8571},
+ {79.2505,0}
+};
+
+static const SFG_StrokeStrip ch60st[] =
+{
+ {3,ch60st0}
+};
+
+static const SFG_StrokeChar ch60 = {81.6105,1,ch60st};
+
+/* char: 0x3d */
+
+static const SFG_StrokeVertex ch61st0[] =
+{
+ {5.7,57.1429},
+ {91.4143,57.1429}
+};
+
+static const SFG_StrokeVertex ch61st1[] =
+{
+ {5.7,28.5714},
+ {91.4143,28.5714}
+};
+
+static const SFG_StrokeStrip ch61st[] =
+{
+ {2,ch61st0},
+ {2,ch61st1}
+};
+
+static const SFG_StrokeChar ch61 = {97.2543,2,ch61st};
+
+/* char: 0x3e */
+
+static const SFG_StrokeVertex ch62st0[] =
+{
+ {2.78,85.7143},
+ {78.9705,42.8571},
+ {2.78,0}
+};
+
+static const SFG_StrokeStrip ch62st[] =
+{
+ {3,ch62st0}
+};
+
+static const SFG_StrokeChar ch62 = {81.6105,1,ch62st};
+
+/* char: 0x3f */
+
+static const SFG_StrokeVertex ch63st0[] =
+{
+ {8.42,76.1905},
+ {8.42,80.9524},
+ {13.1819,90.4762},
+ {17.9438,95.2381},
+ {27.4676,100},
+ {46.5152,100},
+ {56.039,95.2381},
+ {60.801,90.4762},
+ {65.5629,80.9524},
+ {65.5629,71.4286},
+ {60.801,61.9048},
+ {56.039,57.1429},
+ {36.9914,47.619},
+ {36.9914,33.3333}
+};
+
+static const SFG_StrokeVertex ch63st1[] =
+{
+ {36.9914,9.5238},
+ {32.2295,4.7619},
+ {36.9914,0},
+ {41.7533,4.7619},
+ {36.9914,9.5238}
+};
+
+static const SFG_StrokeStrip ch63st[] =
+{
+ {14,ch63st0},
+ {5,ch63st1}
+};
+
+static const SFG_StrokeChar ch63 = {73.9029,2,ch63st};
+
+/* char: 0x40 */
+
+static const SFG_StrokeVertex ch64st0[] =
+{
+ {49.2171,52.381},
+ {39.6933,57.1429},
+ {30.1695,57.1429},
+ {25.4076,47.619},
+ {25.4076,42.8571},
+ {30.1695,33.3333},
+ {39.6933,33.3333},
+ {49.2171,38.0952}
+};
+
+static const SFG_StrokeVertex ch64st1[] =
+{
+ {49.2171,57.1429},
+ {49.2171,38.0952},
+ {53.979,33.3333},
+ {63.5029,33.3333},
+ {68.2648,42.8571},
+ {68.2648,47.619},
+ {63.5029,61.9048},
+ {53.979,71.4286},
+ {39.6933,76.1905},
+ {34.9314,76.1905},
+ {20.6457,71.4286},
+ {11.1219,61.9048},
+ {6.36,47.619},
+ {6.36,42.8571},
+ {11.1219,28.5714},
+ {20.6457,19.0476},
+ {34.9314,14.2857},
+ {39.6933,14.2857},
+ {53.979,19.0476}
+};
+
+static const SFG_StrokeStrip ch64st[] =
+{
+ {8,ch64st0},
+ {19,ch64st1}
+};
+
+static const SFG_StrokeChar ch64 = {74.3648,2,ch64st};
+
+/* char: 0x41 */
+
+static const SFG_StrokeVertex ch65st0[] =
+{
+ {40.5952,100},
+ {2.5,0}
+};
+
+static const SFG_StrokeVertex ch65st1[] =
+{
+ {40.5952,100},
+ {78.6905,0}
+};
+
+static const SFG_StrokeVertex ch65st2[] =
+{
+ {16.7857,33.3333},
+ {64.4048,33.3333}
+};
+
+static const SFG_StrokeStrip ch65st[] =
+{
+ {2,ch65st0},
+ {2,ch65st1},
+ {2,ch65st2}
+};
+
+static const SFG_StrokeChar ch65 = {80.4905,3,ch65st};
+
+/* char: 0x42 */
+
+static const SFG_StrokeVertex ch66st0[] =
+{
+ {11.42,100},
+ {11.42,0}
+};
+
+static const SFG_StrokeVertex ch66st1[] =
+{
+ {11.42,100},
+ {54.2771,100},
+ {68.5629,95.2381},
+ {73.3248,90.4762},
+ {78.0867,80.9524},
+ {78.0867,71.4286},
+ {73.3248,61.9048},
+ {68.5629,57.1429},
+ {54.2771,52.381}
+};
+
+static const SFG_StrokeVertex ch66st2[] =
+{
+ {11.42,52.381},
+ {54.2771,52.381},
+ {68.5629,47.619},
+ {73.3248,42.8571},
+ {78.0867,33.3333},
+ {78.0867,19.0476},
+ {73.3248,9.5238},
+ {68.5629,4.7619},
+ {54.2771,0},
+ {11.42,0}
+};
+
+static const SFG_StrokeStrip ch66st[] =
+{
+ {2,ch66st0},
+ {9,ch66st1},
+ {10,ch66st2}
+};
+
+static const SFG_StrokeChar ch66 = {83.6267,3,ch66st};
+
+/* char: 0x43 */
+
+static const SFG_StrokeVertex ch67st0[] =
+{
+ {78.0886,76.1905},
+ {73.3267,85.7143},
+ {63.8029,95.2381},
+ {54.279,100},
+ {35.2314,100},
+ {25.7076,95.2381},
+ {16.1838,85.7143},
+ {11.4219,76.1905},
+ {6.66,61.9048},
+ {6.66,38.0952},
+ {11.4219,23.8095},
+ {16.1838,14.2857},
+ {25.7076,4.7619},
+ {35.2314,0},
+ {54.279,0},
+ {63.8029,4.7619},
+ {73.3267,14.2857},
+ {78.0886,23.8095}
+};
+
+static const SFG_StrokeStrip ch67st[] =
+{
+ {18,ch67st0}
+};
+
+static const SFG_StrokeChar ch67 = {84.4886,1,ch67st};
+
+/* char: 0x44 */
+
+static const SFG_StrokeVertex ch68st0[] =
+{
+ {11.96,100},
+ {11.96,0}
+};
+
+static const SFG_StrokeVertex ch68st1[] =
+{
+ {11.96,100},
+ {45.2933,100},
+ {59.579,95.2381},
+ {69.1029,85.7143},
+ {73.8648,76.1905},
+ {78.6267,61.9048},
+ {78.6267,38.0952},
+ {73.8648,23.8095},
+ {69.1029,14.2857},
+ {59.579,4.7619},
+ {45.2933,0},
+ {11.96,0}
+};
+
+static const SFG_StrokeStrip ch68st[] =
+{
+ {2,ch68st0},
+ {12,ch68st1}
+};
+
+static const SFG_StrokeChar ch68 = {85.2867,2,ch68st};
+
+/* char: 0x45 */
+
+static const SFG_StrokeVertex ch69st0[] =
+{
+ {11.42,100},
+ {11.42,0}
+};
+
+static const SFG_StrokeVertex ch69st1[] =
+{
+ {11.42,100},
+ {73.3248,100}
+};
+
+static const SFG_StrokeVertex ch69st2[] =
+{
+ {11.42,52.381},
+ {49.5152,52.381}
+};
+
+static const SFG_StrokeVertex ch69st3[] =
+{
+ {11.42,0},
+ {73.3248,0}
+};
+
+static const SFG_StrokeStrip ch69st[] =
+{
+ {2,ch69st0},
+ {2,ch69st1},
+ {2,ch69st2},
+ {2,ch69st3}
+};
+
+static const SFG_StrokeChar ch69 = {78.1848,4,ch69st};
+
+/* char: 0x46 */
+
+static const SFG_StrokeVertex ch70st0[] =
+{
+ {11.42,100},
+ {11.42,0}
+};
+
+static const SFG_StrokeVertex ch70st1[] =
+{
+ {11.42,100},
+ {73.3248,100}
+};
+
+static const SFG_StrokeVertex ch70st2[] =
+{
+ {11.42,52.381},
+ {49.5152,52.381}
+};
+
+static const SFG_StrokeStrip ch70st[] =
+{
+ {2,ch70st0},
+ {2,ch70st1},
+ {2,ch70st2}
+};
+
+static const SFG_StrokeChar ch70 = {78.7448,3,ch70st};
+
+/* char: 0x47 */
+
+static const SFG_StrokeVertex ch71st0[] =
+{
+ {78.4886,76.1905},
+ {73.7267,85.7143},
+ {64.2029,95.2381},
+ {54.679,100},
+ {35.6314,100},
+ {26.1076,95.2381},
+ {16.5838,85.7143},
+ {11.8219,76.1905},
+ {7.06,61.9048},
+ {7.06,38.0952},
+ {11.8219,23.8095},
+ {16.5838,14.2857},
+ {26.1076,4.7619},
+ {35.6314,0},
+ {54.679,0},
+ {64.2029,4.7619},
+ {73.7267,14.2857},
+ {78.4886,23.8095},
+ {78.4886,38.0952}
+};
+
+static const SFG_StrokeVertex ch71st1[] =
+{
+ {54.679,38.0952},
+ {78.4886,38.0952}
+};
+
+static const SFG_StrokeStrip ch71st[] =
+{
+ {19,ch71st0},
+ {2,ch71st1}
+};
+
+static const SFG_StrokeChar ch71 = {89.7686,2,ch71st};
+
+/* char: 0x48 */
+
+static const SFG_StrokeVertex ch72st0[] =
+{
+ {11.42,100},
+ {11.42,0}
+};
+
+static const SFG_StrokeVertex ch72st1[] =
+{
+ {78.0867,100},
+ {78.0867,0}
+};
+
+static const SFG_StrokeVertex ch72st2[] =
+{
+ {11.42,52.381},
+ {78.0867,52.381}
+};
+
+static const SFG_StrokeStrip ch72st[] =
+{
+ {2,ch72st0},
+ {2,ch72st1},
+ {2,ch72st2}
+};
+
+static const SFG_StrokeChar ch72 = {89.0867,3,ch72st};
+
+/* char: 0x49 */
+
+static const SFG_StrokeVertex ch73st0[] =
+{
+ {10.86,100},
+ {10.86,0}
+};
+
+static const SFG_StrokeStrip ch73st[] =
+{
+ {2,ch73st0}
+};
+
+static const SFG_StrokeChar ch73 = {21.3,1,ch73st};
+
+/* char: 0x4a */
+
+static const SFG_StrokeVertex ch74st0[] =
+{
+ {50.119,100},
+ {50.119,23.8095},
+ {45.3571,9.5238},
+ {40.5952,4.7619},
+ {31.0714,0},
+ {21.5476,0},
+ {12.0238,4.7619},
+ {7.2619,9.5238},
+ {2.5,23.8095},
+ {2.5,33.3333}
+};
+
+static const SFG_StrokeStrip ch74st[] =
+{
+ {10,ch74st0}
+};
+
+static const SFG_StrokeChar ch74 = {59.999,1,ch74st};
+
+/* char: 0x4b */
+
+static const SFG_StrokeVertex ch75st0[] =
+{
+ {11.28,100},
+ {11.28,0}
+};
+
+static const SFG_StrokeVertex ch75st1[] =
+{
+ {77.9467,100},
+ {11.28,33.3333}
+};
+
+static const SFG_StrokeVertex ch75st2[] =
+{
+ {35.0895,57.1429},
+ {77.9467,0}
+};
+
+static const SFG_StrokeStrip ch75st[] =
+{
+ {2,ch75st0},
+ {2,ch75st1},
+ {2,ch75st2}
+};
+
+static const SFG_StrokeChar ch75 = {79.3267,3,ch75st};
+
+/* char: 0x4c */
+
+static const SFG_StrokeVertex ch76st0[] =
+{
+ {11.68,100},
+ {11.68,0}
+};
+
+static const SFG_StrokeVertex ch76st1[] =
+{
+ {11.68,0},
+ {68.8229,0}
+};
+
+static const SFG_StrokeStrip ch76st[] =
+{
+ {2,ch76st0},
+ {2,ch76st1}
+};
+
+static const SFG_StrokeChar ch76 = {71.3229,2,ch76st};
+
+/* char: 0x4d */
+
+static const SFG_StrokeVertex ch77st0[] =
+{
+ {10.86,100},
+ {10.86,0}
+};
+
+static const SFG_StrokeVertex ch77st1[] =
+{
+ {10.86,100},
+ {48.9552,0}
+};
+
+static const SFG_StrokeVertex ch77st2[] =
+{
+ {87.0505,100},
+ {48.9552,0}
+};
+
+static const SFG_StrokeVertex ch77st3[] =
+{
+ {87.0505,100},
+ {87.0505,0}
+};
+
+static const SFG_StrokeStrip ch77st[] =
+{
+ {2,ch77st0},
+ {2,ch77st1},
+ {2,ch77st2},
+ {2,ch77st3}
+};
+
+static const SFG_StrokeChar ch77 = {97.2105,4,ch77st};
+
+/* char: 0x4e */
+
+static const SFG_StrokeVertex ch78st0[] =
+{
+ {11.14,100},
+ {11.14,0}
+};
+
+static const SFG_StrokeVertex ch78st1[] =
+{
+ {11.14,100},
+ {77.8067,0}
+};
+
+static const SFG_StrokeVertex ch78st2[] =
+{
+ {77.8067,100},
+ {77.8067,0}
+};
+
+static const SFG_StrokeStrip ch78st[] =
+{
+ {2,ch78st0},
+ {2,ch78st1},
+ {2,ch78st2}
+};
+
+static const SFG_StrokeChar ch78 = {88.8067,3,ch78st};
+
+/* char: 0x4f */
+
+static const SFG_StrokeVertex ch79st0[] =
+{
+ {34.8114,100},
+ {25.2876,95.2381},
+ {15.7638,85.7143},
+ {11.0019,76.1905},
+ {6.24,61.9048},
+ {6.24,38.0952},
+ {11.0019,23.8095},
+ {15.7638,14.2857},
+ {25.2876,4.7619},
+ {34.8114,0},
+ {53.859,0},
+ {63.3829,4.7619},
+ {72.9067,14.2857},
+ {77.6686,23.8095},
+ {82.4305,38.0952},
+ {82.4305,61.9048},
+ {77.6686,76.1905},
+ {72.9067,85.7143},
+ {63.3829,95.2381},
+ {53.859,100},
+ {34.8114,100}
+};
+
+static const SFG_StrokeStrip ch79st[] =
+{
+ {21,ch79st0}
+};
+
+static const SFG_StrokeChar ch79 = {88.8305,1,ch79st};
+
+/* char: 0x50 */
+
+static const SFG_StrokeVertex ch80st0[] =
+{
+ {12.1,100},
+ {12.1,0}
+};
+
+static const SFG_StrokeVertex ch80st1[] =
+{
+ {12.1,100},
+ {54.9571,100},
+ {69.2429,95.2381},
+ {74.0048,90.4762},
+ {78.7667,80.9524},
+ {78.7667,66.6667},
+ {74.0048,57.1429},
+ {69.2429,52.381},
+ {54.9571,47.619},
+ {12.1,47.619}
+};
+
+static const SFG_StrokeStrip ch80st[] =
+{
+ {2,ch80st0},
+ {10,ch80st1}
+};
+
+static const SFG_StrokeChar ch80 = {85.6667,2,ch80st};
+
+/* char: 0x51 */
+
+static const SFG_StrokeVertex ch81st0[] =
+{
+ {33.8714,100},
+ {24.3476,95.2381},
+ {14.8238,85.7143},
+ {10.0619,76.1905},
+ {5.3,61.9048},
+ {5.3,38.0952},
+ {10.0619,23.8095},
+ {14.8238,14.2857},
+ {24.3476,4.7619},
+ {33.8714,0},
+ {52.919,0},
+ {62.4429,4.7619},
+ {71.9667,14.2857},
+ {76.7286,23.8095},
+ {81.4905,38.0952},
+ {81.4905,61.9048},
+ {76.7286,76.1905},
+ {71.9667,85.7143},
+ {62.4429,95.2381},
+ {52.919,100},
+ {33.8714,100}
+};
+
+static const SFG_StrokeVertex ch81st1[] =
+{
+ {48.1571,19.0476},
+ {76.7286,-9.5238}
+};
+
+static const SFG_StrokeStrip ch81st[] =
+{
+ {21,ch81st0},
+ {2,ch81st1}
+};
+
+static const SFG_StrokeChar ch81 = {88.0905,2,ch81st};
+
+/* char: 0x52 */
+
+static const SFG_StrokeVertex ch82st0[] =
+{
+ {11.68,100},
+ {11.68,0}
+};
+
+static const SFG_StrokeVertex ch82st1[] =
+{
+ {11.68,100},
+ {54.5371,100},
+ {68.8229,95.2381},
+ {73.5848,90.4762},
+ {78.3467,80.9524},
+ {78.3467,71.4286},
+ {73.5848,61.9048},
+ {68.8229,57.1429},
+ {54.5371,52.381},
+ {11.68,52.381}
+};
+
+static const SFG_StrokeVertex ch82st2[] =
+{
+ {45.0133,52.381},
+ {78.3467,0}
+};
+
+static const SFG_StrokeStrip ch82st[] =
+{
+ {2,ch82st0},
+ {10,ch82st1},
+ {2,ch82st2}
+};
+
+static const SFG_StrokeChar ch82 = {82.3667,3,ch82st};
+
+/* char: 0x53 */
+
+static const SFG_StrokeVertex ch83st0[] =
+{
+ {74.6667,85.7143},
+ {65.1429,95.2381},
+ {50.8571,100},
+ {31.8095,100},
+ {17.5238,95.2381},
+ {8,85.7143},
+ {8,76.1905},
+ {12.7619,66.6667},
+ {17.5238,61.9048},
+ {27.0476,57.1429},
+ {55.619,47.619},
+ {65.1429,42.8571},
+ {69.9048,38.0952},
+ {74.6667,28.5714},
+ {74.6667,14.2857},
+ {65.1429,4.7619},
+ {50.8571,0},
+ {31.8095,0},
+ {17.5238,4.7619},
+ {8,14.2857}
+};
+
+static const SFG_StrokeStrip ch83st[] =
+{
+ {20,ch83st0}
+};
+
+static const SFG_StrokeChar ch83 = {80.8267,1,ch83st};
+
+/* char: 0x54 */
+
+static const SFG_StrokeVertex ch84st0[] =
+{
+ {35.6933,100},
+ {35.6933,0}
+};
+
+static const SFG_StrokeVertex ch84st1[] =
+{
+ {2.36,100},
+ {69.0267,100}
+};
+
+static const SFG_StrokeStrip ch84st[] =
+{
+ {2,ch84st0},
+ {2,ch84st1}
+};
+
+static const SFG_StrokeChar ch84 = {71.9467,2,ch84st};
+
+/* char: 0x55 */
+
+static const SFG_StrokeVertex ch85st0[] =
+{
+ {11.54,100},
+ {11.54,28.5714},
+ {16.3019,14.2857},
+ {25.8257,4.7619},
+ {40.1114,0},
+ {49.6352,0},
+ {63.921,4.7619},
+ {73.4448,14.2857},
+ {78.2067,28.5714},
+ {78.2067,100}
+};
+
+static const SFG_StrokeStrip ch85st[] =
+{
+ {10,ch85st0}
+};
+
+static const SFG_StrokeChar ch85 = {89.4867,1,ch85st};
+
+/* char: 0x56 */
+
+static const SFG_StrokeVertex ch86st0[] =
+{
+ {2.36,100},
+ {40.4552,0}
+};
+
+static const SFG_StrokeVertex ch86st1[] =
+{
+ {78.5505,100},
+ {40.4552,0}
+};
+
+static const SFG_StrokeStrip ch86st[] =
+{
+ {2,ch86st0},
+ {2,ch86st1}
+};
+
+static const SFG_StrokeChar ch86 = {81.6105,2,ch86st};
+
+/* char: 0x57 */
+
+static const SFG_StrokeVertex ch87st0[] =
+{
+ {2.22,100},
+ {26.0295,0}
+};
+
+static const SFG_StrokeVertex ch87st1[] =
+{
+ {49.839,100},
+ {26.0295,0}
+};
+
+static const SFG_StrokeVertex ch87st2[] =
+{
+ {49.839,100},
+ {73.6486,0}
+};
+
+static const SFG_StrokeVertex ch87st3[] =
+{
+ {97.4581,100},
+ {73.6486,0}
+};
+
+static const SFG_StrokeStrip ch87st[] =
+{
+ {2,ch87st0},
+ {2,ch87st1},
+ {2,ch87st2},
+ {2,ch87st3}
+};
+
+static const SFG_StrokeChar ch87 = {100.518,4,ch87st};
+
+/* char: 0x58 */
+
+static const SFG_StrokeVertex ch88st0[] =
+{
+ {2.5,100},
+ {69.1667,0}
+};
+
+static const SFG_StrokeVertex ch88st1[] =
+{
+ {69.1667,100},
+ {2.5,0}
+};
+
+static const SFG_StrokeStrip ch88st[] =
+{
+ {2,ch88st0},
+ {2,ch88st1}
+};
+
+static const SFG_StrokeChar ch88 = {72.3667,2,ch88st};
+
+/* char: 0x59 */
+
+static const SFG_StrokeVertex ch89st0[] =
+{
+ {1.52,100},
+ {39.6152,52.381},
+ {39.6152,0}
+};
+
+static const SFG_StrokeVertex ch89st1[] =
+{
+ {77.7105,100},
+ {39.6152,52.381}
+};
+
+static const SFG_StrokeStrip ch89st[] =
+{
+ {3,ch89st0},
+ {2,ch89st1}
+};
+
+static const SFG_StrokeChar ch89 = {79.6505,2,ch89st};
+
+/* char: 0x5a */
+
+static const SFG_StrokeVertex ch90st0[] =
+{
+ {69.1667,100},
+ {2.5,0}
+};
+
+static const SFG_StrokeVertex ch90st1[] =
+{
+ {2.5,100},
+ {69.1667,100}
+};
+
+static const SFG_StrokeVertex ch90st2[] =
+{
+ {2.5,0},
+ {69.1667,0}
+};
+
+static const SFG_StrokeStrip ch90st[] =
+{
+ {2,ch90st0},
+ {2,ch90st1},
+ {2,ch90st2}
+};
+
+static const SFG_StrokeChar ch90 = {73.7467,3,ch90st};
+
+/* char: 0x5b */
+
+static const SFG_StrokeVertex ch91st0[] =
+{
+ {7.78,119.048},
+ {7.78,-33.3333}
+};
+
+static const SFG_StrokeVertex ch91st1[] =
+{
+ {12.5419,119.048},
+ {12.5419,-33.3333}
+};
+
+static const SFG_StrokeVertex ch91st2[] =
+{
+ {7.78,119.048},
+ {41.1133,119.048}
+};
+
+static const SFG_StrokeVertex ch91st3[] =
+{
+ {7.78,-33.3333},
+ {41.1133,-33.3333}
+};
+
+static const SFG_StrokeStrip ch91st[] =
+{
+ {2,ch91st0},
+ {2,ch91st1},
+ {2,ch91st2},
+ {2,ch91st3}
+};
+
+static const SFG_StrokeChar ch91 = {46.1133,4,ch91st};
+
+/* char: 0x5c */
+
+static const SFG_StrokeVertex ch92st0[] =
+{
+ {5.84,100},
+ {72.5067,-14.2857}
+};
+
+static const SFG_StrokeStrip ch92st[] =
+{
+ {2,ch92st0}
+};
+
+static const SFG_StrokeChar ch92 = {78.2067,1,ch92st};
+
+/* char: 0x5d */
+
+static const SFG_StrokeVertex ch93st0[] =
+{
+ {33.0114,119.048},
+ {33.0114,-33.3333}
+};
+
+static const SFG_StrokeVertex ch93st1[] =
+{
+ {37.7733,119.048},
+ {37.7733,-33.3333}
+};
+
+static const SFG_StrokeVertex ch93st2[] =
+{
+ {4.44,119.048},
+ {37.7733,119.048}
+};
+
+static const SFG_StrokeVertex ch93st3[] =
+{
+ {4.44,-33.3333},
+ {37.7733,-33.3333}
+};
+
+static const SFG_StrokeStrip ch93st[] =
+{
+ {2,ch93st0},
+ {2,ch93st1},
+ {2,ch93st2},
+ {2,ch93st3}
+};
+
+static const SFG_StrokeChar ch93 = {46.3933,4,ch93st};
+
+/* char: 0x5e */
+
+static const SFG_StrokeVertex ch94st0[] =
+{
+ {44.0752,109.524},
+ {5.98,42.8571}
+};
+
+static const SFG_StrokeVertex ch94st1[] =
+{
+ {44.0752,109.524},
+ {82.1705,42.8571}
+};
+
+static const SFG_StrokeStrip ch94st[] =
+{
+ {2,ch94st0},
+ {2,ch94st1}
+};
+
+static const SFG_StrokeChar ch94 = {90.2305,2,ch94st};
+
+/* char: 0x5f */
+
+static const SFG_StrokeVertex ch95st0[] =
+{
+ {-1.1,-33.3333},
+ {103.662,-33.3333},
+ {103.662,-28.5714},
+ {-1.1,-28.5714},
+ {-1.1,-33.3333}
+};
+
+static const SFG_StrokeStrip ch95st[] =
+{
+ {5,ch95st0}
+};
+
+static const SFG_StrokeChar ch95 = {104.062,1,ch95st};
+
+/* char: 0x60 */
+
+static const SFG_StrokeVertex ch96st0[] =
+{
+ {33.0219,100},
+ {56.8314,71.4286}
+};
+
+static const SFG_StrokeVertex ch96st1[] =
+{
+ {33.0219,100},
+ {28.26,95.2381},
+ {56.8314,71.4286}
+};
+
+static const SFG_StrokeStrip ch96st[] =
+{
+ {2,ch96st0},
+ {3,ch96st1}
+};
+
+static const SFG_StrokeChar ch96 = {83.5714,2,ch96st};
+
+/* char: 0x61 */
+
+static const SFG_StrokeVertex ch97st0[] =
+{
+ {63.8229,66.6667},
+ {63.8229,0}
+};
+
+static const SFG_StrokeVertex ch97st1[] =
+{
+ {63.8229,52.381},
+ {54.299,61.9048},
+ {44.7752,66.6667},
+ {30.4895,66.6667},
+ {20.9657,61.9048},
+ {11.4419,52.381},
+ {6.68,38.0952},
+ {6.68,28.5714},
+ {11.4419,14.2857},
+ {20.9657,4.7619},
+ {30.4895,0},
+ {44.7752,0},
+ {54.299,4.7619},
+ {63.8229,14.2857}
+};
+
+static const SFG_StrokeStrip ch97st[] =
+{
+ {2,ch97st0},
+ {14,ch97st1}
+};
+
+static const SFG_StrokeChar ch97 = {66.6029,2,ch97st};
+
+/* char: 0x62 */
+
+static const SFG_StrokeVertex ch98st0[] =
+{
+ {8.76,100},
+ {8.76,0}
+};
+
+static const SFG_StrokeVertex ch98st1[] =
+{
+ {8.76,52.381},
+ {18.2838,61.9048},
+ {27.8076,66.6667},
+ {42.0933,66.6667},
+ {51.6171,61.9048},
+ {61.141,52.381},
+ {65.9029,38.0952},
+ {65.9029,28.5714},
+ {61.141,14.2857},
+ {51.6171,4.7619},
+ {42.0933,0},
+ {27.8076,0},
+ {18.2838,4.7619},
+ {8.76,14.2857}
+};
+
+static const SFG_StrokeStrip ch98st[] =
+{
+ {2,ch98st0},
+ {14,ch98st1}
+};
+
+static const SFG_StrokeChar ch98 = {70.4629,2,ch98st};
+
+/* char: 0x63 */
+
+static const SFG_StrokeVertex ch99st0[] =
+{
+ {62.6629,52.381},
+ {53.139,61.9048},
+ {43.6152,66.6667},
+ {29.3295,66.6667},
+ {19.8057,61.9048},
+ {10.2819,52.381},
+ {5.52,38.0952},
+ {5.52,28.5714},
+ {10.2819,14.2857},
+ {19.8057,4.7619},
+ {29.3295,0},
+ {43.6152,0},
+ {53.139,4.7619},
+ {62.6629,14.2857}
+};
+
+static const SFG_StrokeStrip ch99st[] =
+{
+ {14,ch99st0}
+};
+
+static const SFG_StrokeChar ch99 = {68.9229,1,ch99st};
+
+/* char: 0x64 */
+
+static const SFG_StrokeVertex ch100st0[] =
+{
+ {61.7829,100},
+ {61.7829,0}
+};
+
+static const SFG_StrokeVertex ch100st1[] =
+{
+ {61.7829,52.381},
+ {52.259,61.9048},
+ {42.7352,66.6667},
+ {28.4495,66.6667},
+ {18.9257,61.9048},
+ {9.4019,52.381},
+ {4.64,38.0952},
+ {4.64,28.5714},
+ {9.4019,14.2857},
+ {18.9257,4.7619},
+ {28.4495,0},
+ {42.7352,0},
+ {52.259,4.7619},
+ {61.7829,14.2857}
+};
+
+static const SFG_StrokeStrip ch100st[] =
+{
+ {2,ch100st0},
+ {14,ch100st1}
+};
+
+static const SFG_StrokeChar ch100 = {70.2629,2,ch100st};
+
+/* char: 0x65 */
+
+static const SFG_StrokeVertex ch101st0[] =
+{
+ {5.72,38.0952},
+ {62.8629,38.0952},
+ {62.8629,47.619},
+ {58.101,57.1429},
+ {53.339,61.9048},
+ {43.8152,66.6667},
+ {29.5295,66.6667},
+ {20.0057,61.9048},
+ {10.4819,52.381},
+ {5.72,38.0952},
+ {5.72,28.5714},
+ {10.4819,14.2857},
+ {20.0057,4.7619},
+ {29.5295,0},
+ {43.8152,0},
+ {53.339,4.7619},
+ {62.8629,14.2857}
+};
+
+static const SFG_StrokeStrip ch101st[] =
+{
+ {17,ch101st0}
+};
+
+static const SFG_StrokeChar ch101 = {68.5229,1,ch101st};
+
+/* char: 0x66 */
+
+static const SFG_StrokeVertex ch102st0[] =
+{
+ {38.7752,100},
+ {29.2514,100},
+ {19.7276,95.2381},
+ {14.9657,80.9524},
+ {14.9657,0}
+};
+
+static const SFG_StrokeVertex ch102st1[] =
+{
+ {0.68,66.6667},
+ {34.0133,66.6667}
+};
+
+static const SFG_StrokeStrip ch102st[] =
+{
+ {5,ch102st0},
+ {2,ch102st1}
+};
+
+static const SFG_StrokeChar ch102 = {38.6552,2,ch102st};
+
+/* char: 0x67 */
+
+static const SFG_StrokeVertex ch103st0[] =
+{
+ {62.5029,66.6667},
+ {62.5029,-9.5238},
+ {57.741,-23.8095},
+ {52.979,-28.5714},
+ {43.4552,-33.3333},
+ {29.1695,-33.3333},
+ {19.6457,-28.5714}
+};
+
+static const SFG_StrokeVertex ch103st1[] =
+{
+ {62.5029,52.381},
+ {52.979,61.9048},
+ {43.4552,66.6667},
+ {29.1695,66.6667},
+ {19.6457,61.9048},
+ {10.1219,52.381},
+ {5.36,38.0952},
+ {5.36,28.5714},
+ {10.1219,14.2857},
+ {19.6457,4.7619},
+ {29.1695,0},
+ {43.4552,0},
+ {52.979,4.7619},
+ {62.5029,14.2857}
+};
+
+static const SFG_StrokeStrip ch103st[] =
+{
+ {7,ch103st0},
+ {14,ch103st1}
+};
+
+static const SFG_StrokeChar ch103 = {70.9829,2,ch103st};
+
+/* char: 0x68 */
+
+static const SFG_StrokeVertex ch104st0[] =
+{
+ {9.6,100},
+ {9.6,0}
+};
+
+static const SFG_StrokeVertex ch104st1[] =
+{
+ {9.6,47.619},
+ {23.8857,61.9048},
+ {33.4095,66.6667},
+ {47.6952,66.6667},
+ {57.219,61.9048},
+ {61.981,47.619},
+ {61.981,0}
+};
+
+static const SFG_StrokeStrip ch104st[] =
+{
+ {2,ch104st0},
+ {7,ch104st1}
+};
+
+static const SFG_StrokeChar ch104 = {71.021,2,ch104st};
+
+/* char: 0x69 */
+
+static const SFG_StrokeVertex ch105st0[] =
+{
+ {10.02,100},
+ {14.7819,95.2381},
+ {19.5438,100},
+ {14.7819,104.762},
+ {10.02,100}
+};
+
+static const SFG_StrokeVertex ch105st1[] =
+{
+ {14.7819,66.6667},
+ {14.7819,0}
+};
+
+static const SFG_StrokeStrip ch105st[] =
+{
+ {5,ch105st0},
+ {2,ch105st1}
+};
+
+static const SFG_StrokeChar ch105 = {28.8638,2,ch105st};
+
+/* char: 0x6a */
+
+static const SFG_StrokeVertex ch106st0[] =
+{
+ {17.3876,100},
+ {22.1495,95.2381},
+ {26.9114,100},
+ {22.1495,104.762},
+ {17.3876,100}
+};
+
+static const SFG_StrokeVertex ch106st1[] =
+{
+ {22.1495,66.6667},
+ {22.1495,-14.2857},
+ {17.3876,-28.5714},
+ {7.8638,-33.3333},
+ {-1.66,-33.3333}
+};
+
+static const SFG_StrokeStrip ch106st[] =
+{
+ {5,ch106st0},
+ {5,ch106st1}
+};
+
+static const SFG_StrokeChar ch106 = {36.2314,2,ch106st};
+
+/* char: 0x6b */
+
+static const SFG_StrokeVertex ch107st0[] =
+{
+ {9.6,100},
+ {9.6,0}
+};
+
+static const SFG_StrokeVertex ch107st1[] =
+{
+ {57.219,66.6667},
+ {9.6,19.0476}
+};
+
+static const SFG_StrokeVertex ch107st2[] =
+{
+ {28.6476,38.0952},
+ {61.981,0}
+};
+
+static const SFG_StrokeStrip ch107st[] =
+{
+ {2,ch107st0},
+ {2,ch107st1},
+ {2,ch107st2}
+};
+
+static const SFG_StrokeChar ch107 = {62.521,3,ch107st};
+
+/* char: 0x6c */
+
+static const SFG_StrokeVertex ch108st0[] =
+{
+ {10.02,100},
+ {10.02,0}
+};
+
+static const SFG_StrokeStrip ch108st[] =
+{
+ {2,ch108st0}
+};
+
+static const SFG_StrokeChar ch108 = {19.34,1,ch108st};
+
+/* char: 0x6d */
+
+static const SFG_StrokeVertex ch109st0[] =
+{
+ {9.6,66.6667},
+ {9.6,0}
+};
+
+static const SFG_StrokeVertex ch109st1[] =
+{
+ {9.6,47.619},
+ {23.8857,61.9048},
+ {33.4095,66.6667},
+ {47.6952,66.6667},
+ {57.219,61.9048},
+ {61.981,47.619},
+ {61.981,0}
+};
+
+static const SFG_StrokeVertex ch109st2[] =
+{
+ {61.981,47.619},
+ {76.2667,61.9048},
+ {85.7905,66.6667},
+ {100.076,66.6667},
+ {109.6,61.9048},
+ {114.362,47.619},
+ {114.362,0}
+};
+
+static const SFG_StrokeStrip ch109st[] =
+{
+ {2,ch109st0},
+ {7,ch109st1},
+ {7,ch109st2}
+};
+
+static const SFG_StrokeChar ch109 = {123.962,3,ch109st};
+
+/* char: 0x6e */
+
+static const SFG_StrokeVertex ch110st0[] =
+{
+ {9.18,66.6667},
+ {9.18,0}
+};
+
+static const SFG_StrokeVertex ch110st1[] =
+{
+ {9.18,47.619},
+ {23.4657,61.9048},
+ {32.9895,66.6667},
+ {47.2752,66.6667},
+ {56.799,61.9048},
+ {61.561,47.619},
+ {61.561,0}
+};
+
+static const SFG_StrokeStrip ch110st[] =
+{
+ {2,ch110st0},
+ {7,ch110st1}
+};
+
+static const SFG_StrokeChar ch110 = {70.881,2,ch110st};
+
+/* char: 0x6f */
+
+static const SFG_StrokeVertex ch111st0[] =
+{
+ {28.7895,66.6667},
+ {19.2657,61.9048},
+ {9.7419,52.381},
+ {4.98,38.0952},
+ {4.98,28.5714},
+ {9.7419,14.2857},
+ {19.2657,4.7619},
+ {28.7895,0},
+ {43.0752,0},
+ {52.599,4.7619},
+ {62.1229,14.2857},
+ {66.8848,28.5714},
+ {66.8848,38.0952},
+ {62.1229,52.381},
+ {52.599,61.9048},
+ {43.0752,66.6667},
+ {28.7895,66.6667}
+};
+
+static const SFG_StrokeStrip ch111st[] =
+{
+ {17,ch111st0}
+};
+
+static const SFG_StrokeChar ch111 = {71.7448,1,ch111st};
+
+/* char: 0x70 */
+
+static const SFG_StrokeVertex ch112st0[] =
+{
+ {9.46,66.6667},
+ {9.46,-33.3333}
+};
+
+static const SFG_StrokeVertex ch112st1[] =
+{
+ {9.46,52.381},
+ {18.9838,61.9048},
+ {28.5076,66.6667},
+ {42.7933,66.6667},
+ {52.3171,61.9048},
+ {61.841,52.381},
+ {66.6029,38.0952},
+ {66.6029,28.5714},
+ {61.841,14.2857},
+ {52.3171,4.7619},
+ {42.7933,0},
+ {28.5076,0},
+ {18.9838,4.7619},
+ {9.46,14.2857}
+};
+
+static const SFG_StrokeStrip ch112st[] =
+{
+ {2,ch112st0},
+ {14,ch112st1}
+};
+
+static const SFG_StrokeChar ch112 = {70.8029,2,ch112st};
+
+/* char: 0x71 */
+
+static const SFG_StrokeVertex ch113st0[] =
+{
+ {61.9829,66.6667},
+ {61.9829,-33.3333}
+};
+
+static const SFG_StrokeVertex ch113st1[] =
+{
+ {61.9829,52.381},
+ {52.459,61.9048},
+ {42.9352,66.6667},
+ {28.6495,66.6667},
+ {19.1257,61.9048},
+ {9.6019,52.381},
+ {4.84,38.0952},
+ {4.84,28.5714},
+ {9.6019,14.2857},
+ {19.1257,4.7619},
+ {28.6495,0},
+ {42.9352,0},
+ {52.459,4.7619},
+ {61.9829,14.2857}
+};
+
+static const SFG_StrokeStrip ch113st[] =
+{
+ {2,ch113st0},
+ {14,ch113st1}
+};
+
+static const SFG_StrokeChar ch113 = {70.7429,2,ch113st};
+
+/* char: 0x72 */
+
+static const SFG_StrokeVertex ch114st0[] =
+{
+ {9.46,66.6667},
+ {9.46,0}
+};
+
+static const SFG_StrokeVertex ch114st1[] =
+{
+ {9.46,38.0952},
+ {14.2219,52.381},
+ {23.7457,61.9048},
+ {33.2695,66.6667},
+ {47.5552,66.6667}
+};
+
+static const SFG_StrokeStrip ch114st[] =
+{
+ {2,ch114st0},
+ {5,ch114st1}
+};
+
+static const SFG_StrokeChar ch114 = {49.4952,2,ch114st};
+
+/* char: 0x73 */
+
+static const SFG_StrokeVertex ch115st0[] =
+{
+ {57.081,52.381},
+ {52.319,61.9048},
+ {38.0333,66.6667},
+ {23.7476,66.6667},
+ {9.4619,61.9048},
+ {4.7,52.381},
+ {9.4619,42.8571},
+ {18.9857,38.0952},
+ {42.7952,33.3333},
+ {52.319,28.5714},
+ {57.081,19.0476},
+ {57.081,14.2857},
+ {52.319,4.7619},
+ {38.0333,0},
+ {23.7476,0},
+ {9.4619,4.7619},
+ {4.7,14.2857}
+};
+
+static const SFG_StrokeStrip ch115st[] =
+{
+ {17,ch115st0}
+};
+
+static const SFG_StrokeChar ch115 = {62.321,1,ch115st};
+
+/* char: 0x74 */
+
+static const SFG_StrokeVertex ch116st0[] =
+{
+ {14.8257,100},
+ {14.8257,19.0476},
+ {19.5876,4.7619},
+ {29.1114,0},
+ {38.6352,0}
+};
+
+static const SFG_StrokeVertex ch116st1[] =
+{
+ {0.54,66.6667},
+ {33.8733,66.6667}
+};
+
+static const SFG_StrokeStrip ch116st[] =
+{
+ {5,ch116st0},
+ {2,ch116st1}
+};
+
+static const SFG_StrokeChar ch116 = {39.3152,2,ch116st};
+
+/* char: 0x75 */
+
+static const SFG_StrokeVertex ch117st0[] =
+{
+ {9.46,66.6667},
+ {9.46,19.0476},
+ {14.2219,4.7619},
+ {23.7457,0},
+ {38.0314,0},
+ {47.5552,4.7619},
+ {61.841,19.0476}
+};
+
+static const SFG_StrokeVertex ch117st1[] =
+{
+ {61.841,66.6667},
+ {61.841,0}
+};
+
+static const SFG_StrokeStrip ch117st[] =
+{
+ {7,ch117st0},
+ {2,ch117st1}
+};
+
+static const SFG_StrokeChar ch117 = {71.161,2,ch117st};
+
+/* char: 0x76 */
+
+static const SFG_StrokeVertex ch118st0[] =
+{
+ {1.8,66.6667},
+ {30.3714,0}
+};
+
+static const SFG_StrokeVertex ch118st1[] =
+{
+ {58.9429,66.6667},
+ {30.3714,0}
+};
+
+static const SFG_StrokeStrip ch118st[] =
+{
+ {2,ch118st0},
+ {2,ch118st1}
+};
+
+static const SFG_StrokeChar ch118 = {60.6029,2,ch118st};
+
+/* char: 0x77 */
+
+static const SFG_StrokeVertex ch119st0[] =
+{
+ {2.5,66.6667},
+ {21.5476,0}
+};
+
+static const SFG_StrokeVertex ch119st1[] =
+{
+ {40.5952,66.6667},
+ {21.5476,0}
+};
+
+static const SFG_StrokeVertex ch119st2[] =
+{
+ {40.5952,66.6667},
+ {59.6429,0}
+};
+
+static const SFG_StrokeVertex ch119st3[] =
+{
+ {78.6905,66.6667},
+ {59.6429,0}
+};
+
+static const SFG_StrokeStrip ch119st[] =
+{
+ {2,ch119st0},
+ {2,ch119st1},
+ {2,ch119st2},
+ {2,ch119st3}
+};
+
+static const SFG_StrokeChar ch119 = {80.4905,4,ch119st};
+
+/* char: 0x78 */
+
+static const SFG_StrokeVertex ch120st0[] =
+{
+ {1.66,66.6667},
+ {54.041,0}
+};
+
+static const SFG_StrokeVertex ch120st1[] =
+{
+ {54.041,66.6667},
+ {1.66,0}
+};
+
+static const SFG_StrokeStrip ch120st[] =
+{
+ {2,ch120st0},
+ {2,ch120st1}
+};
+
+static const SFG_StrokeChar ch120 = {56.401,2,ch120st};
+
+/* char: 0x79 */
+
+static const SFG_StrokeVertex ch121st0[] =
+{
+ {6.5619,66.6667},
+ {35.1333,0}
+};
+
+static const SFG_StrokeVertex ch121st1[] =
+{
+ {63.7048,66.6667},
+ {35.1333,0},
+ {25.6095,-19.0476},
+ {16.0857,-28.5714},
+ {6.5619,-33.3333},
+ {1.8,-33.3333}
+};
+
+static const SFG_StrokeStrip ch121st[] =
+{
+ {2,ch121st0},
+ {6,ch121st1}
+};
+
+static const SFG_StrokeChar ch121 = {66.0648,2,ch121st};
+
+/* char: 0x7a */
+
+static const SFG_StrokeVertex ch122st0[] =
+{
+ {56.821,66.6667},
+ {4.44,0}
+};
+
+static const SFG_StrokeVertex ch122st1[] =
+{
+ {4.44,66.6667},
+ {56.821,66.6667}
+};
+
+static const SFG_StrokeVertex ch122st2[] =
+{
+ {4.44,0},
+ {56.821,0}
+};
+
+static const SFG_StrokeStrip ch122st[] =
+{
+ {2,ch122st0},
+ {2,ch122st1},
+ {2,ch122st2}
+};
+
+static const SFG_StrokeChar ch122 = {61.821,3,ch122st};
+
+/* char: 0x7b */
+
+static const SFG_StrokeVertex ch123st0[] =
+{
+ {31.1895,119.048},
+ {21.6657,114.286},
+ {16.9038,109.524},
+ {12.1419,100},
+ {12.1419,90.4762},
+ {16.9038,80.9524},
+ {21.6657,76.1905},
+ {26.4276,66.6667},
+ {26.4276,57.1429},
+ {16.9038,47.619}
+};
+
+static const SFG_StrokeVertex ch123st1[] =
+{
+ {21.6657,114.286},
+ {16.9038,104.762},
+ {16.9038,95.2381},
+ {21.6657,85.7143},
+ {26.4276,80.9524},
+ {31.1895,71.4286},
+ {31.1895,61.9048},
+ {26.4276,52.381},
+ {7.38,42.8571},
+ {26.4276,33.3333},
+ {31.1895,23.8095},
+ {31.1895,14.2857},
+ {26.4276,4.7619},
+ {21.6657,0},
+ {16.9038,-9.5238},
+ {16.9038,-19.0476},
+ {21.6657,-28.5714}
+};
+
+static const SFG_StrokeVertex ch123st2[] =
+{
+ {16.9038,38.0952},
+ {26.4276,28.5714},
+ {26.4276,19.0476},
+ {21.6657,9.5238},
+ {16.9038,4.7619},
+ {12.1419,-4.7619},
+ {12.1419,-14.2857},
+ {16.9038,-23.8095},
+ {21.6657,-28.5714},
+ {31.1895,-33.3333}
+};
+
+static const SFG_StrokeStrip ch123st[] =
+{
+ {10,ch123st0},
+ {17,ch123st1},
+ {10,ch123st2}
+};
+
+static const SFG_StrokeChar ch123 = {41.6295,3,ch123st};
+
+/* char: 0x7c */
+
+static const SFG_StrokeVertex ch124st0[] =
+{
+ {11.54,119.048},
+ {11.54,-33.3333}
+};
+
+static const SFG_StrokeStrip ch124st[] =
+{
+ {2,ch124st0}
+};
+
+static const SFG_StrokeChar ch124 = {23.78,1,ch124st};
+
+/* char: 0x7d */
+
+static const SFG_StrokeVertex ch125st0[] =
+{
+ {9.18,119.048},
+ {18.7038,114.286},
+ {23.4657,109.524},
+ {28.2276,100},
+ {28.2276,90.4762},
+ {23.4657,80.9524},
+ {18.7038,76.1905},
+ {13.9419,66.6667},
+ {13.9419,57.1429},
+ {23.4657,47.619}
+};
+
+static const SFG_StrokeVertex ch125st1[] =
+{
+ {18.7038,114.286},
+ {23.4657,104.762},
+ {23.4657,95.2381},
+ {18.7038,85.7143},
+ {13.9419,80.9524},
+ {9.18,71.4286},
+ {9.18,61.9048},
+ {13.9419,52.381},
+ {32.9895,42.8571},
+ {13.9419,33.3333},
+ {9.18,23.8095},
+ {9.18,14.2857},
+ {13.9419,4.7619},
+ {18.7038,0},
+ {23.4657,-9.5238},
+ {23.4657,-19.0476},
+ {18.7038,-28.5714}
+};
+
+static const SFG_StrokeVertex ch125st2[] =
+{
+ {23.4657,38.0952},
+ {13.9419,28.5714},
+ {13.9419,19.0476},
+ {18.7038,9.5238},
+ {23.4657,4.7619},
+ {28.2276,-4.7619},
+ {28.2276,-14.2857},
+ {23.4657,-23.8095},
+ {18.7038,-28.5714},
+ {9.18,-33.3333}
+};
+
+static const SFG_StrokeStrip ch125st[] =
+{
+ {10,ch125st0},
+ {17,ch125st1},
+ {10,ch125st2}
+};
+
+static const SFG_StrokeChar ch125 = {41.4695,3,ch125st};
+
+/* char: 0x7e */
+
+static const SFG_StrokeVertex ch126st0[] =
+{
+ {2.92,28.5714},
+ {2.92,38.0952},
+ {7.6819,52.381},
+ {17.2057,57.1429},
+ {26.7295,57.1429},
+ {36.2533,52.381},
+ {55.301,38.0952},
+ {64.8248,33.3333},
+ {74.3486,33.3333},
+ {83.8724,38.0952},
+ {88.6343,47.619}
+};
+
+static const SFG_StrokeVertex ch126st1[] =
+{
+ {2.92,38.0952},
+ {7.6819,47.619},
+ {17.2057,52.381},
+ {26.7295,52.381},
+ {36.2533,47.619},
+ {55.301,33.3333},
+ {64.8248,28.5714},
+ {74.3486,28.5714},
+ {83.8724,33.3333},
+ {88.6343,47.619},
+ {88.6343,57.1429}
+};
+
+static const SFG_StrokeStrip ch126st[] =
+{
+ {11,ch126st0},
+ {11,ch126st1}
+};
+
+static const SFG_StrokeChar ch126 = {91.2743,2,ch126st};
+
+/* char: 0x7f */
+
+static const SFG_StrokeVertex ch127st0[] =
+{
+ {52.381,100},
+ {14.2857,-33.3333}
+};
+
+static const SFG_StrokeVertex ch127st1[] =
+{
+ {28.5714,66.6667},
+ {14.2857,61.9048},
+ {4.7619,52.381},
+ {0,38.0952},
+ {0,23.8095},
+ {4.7619,14.2857},
+ {14.2857,4.7619},
+ {28.5714,0},
+ {38.0952,0},
+ {52.381,4.7619},
+ {61.9048,14.2857},
+ {66.6667,28.5714},
+ {66.6667,42.8571},
+ {61.9048,52.381},
+ {52.381,61.9048},
+ {38.0952,66.6667},
+ {28.5714,66.6667}
+};
+
+static const SFG_StrokeStrip ch127st[] =
+{
+ {2,ch127st0},
+ {17,ch127st1}
+};
+
+static const SFG_StrokeChar ch127 = {66.6667,2,ch127st};
+
+static const SFG_StrokeChar *chars[] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ &ch32, &ch33, &ch34, &ch35, &ch36, &ch37, &ch38, &ch39,
+ &ch40, &ch41, &ch42, &ch43, &ch44, &ch45, &ch46, &ch47,
+ &ch48, &ch49, &ch50, &ch51, &ch52, &ch53, &ch54, &ch55,
+ &ch56, &ch57, &ch58, &ch59, &ch60, &ch61, &ch62, &ch63,
+ &ch64, &ch65, &ch66, &ch67, &ch68, &ch69, &ch70, &ch71,
+ &ch72, &ch73, &ch74, &ch75, &ch76, &ch77, &ch78, &ch79,
+ &ch80, &ch81, &ch82, &ch83, &ch84, &ch85, &ch86, &ch87,
+ &ch88, &ch89, &ch90, &ch91, &ch92, &ch93, &ch94, &ch95,
+ &ch96, &ch97, &ch98, &ch99, &ch100, &ch101, &ch102, &ch103,
+ &ch104, &ch105, &ch106, &ch107, &ch108, &ch109, &ch110, &ch111,
+ &ch112, &ch113, &ch114, &ch115, &ch116, &ch117, &ch118, &ch119,
+ &ch120, &ch121, &ch122, &ch123, &ch124, &ch125, &ch126, &ch127
+};
+
+const SFG_StrokeFont fgStrokeRoman = {"Roman",128,152.381,chars};
diff --git a/src/freeglut_structure.c b/src/freeglut_structure.c
new file mode 100644 (file)
index 0000000..6b54d50
--- /dev/null
@@ -0,0 +1,721 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-structure"
+
+#include "../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;
+
+
+/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
+
+/*
+ * 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 )
+{
+    /*
+     * Have the window object created
+     */
+    SFG_Window* window = calloc( sizeof(SFG_Window), 1 );
+    int fakeArgc = 0;
+
+    /*
+     * If the freeglut internals haven't been initialized yet,
+     * do it now. Hack's idea courtesy of Chris Purnell...
+     */
+    if( !fgState.Time.Set )
+        glutInit( &fakeArgc, NULL );
+
+    /*
+     * Initialize the object properties
+     */
+    window->ID = ++fgStructure.WindowID;
+
+    /*
+     * Initialize the children list
+     */
+    fgListInit( &window->Children );
+
+    /*
+     * Does this window have a parent?
+     */
+    if( parent != NULL )
+    {
+        /*
+         * That's quite right, attach this windows as a child window
+         */
+       fgListAppend( &parent->Children, &window->Node );
+        window->Parent = parent;
+    }
+    else
+    {
+        /*
+         * Otherwise add the newly created window to the topmost windows list
+         */
+       fgListAppend( &fgStructure.Windows, &window->Node );
+    }
+
+    /*
+     * Set the default mouse cursor and reset the modifiers value
+     */
+    window->State.Cursor    = GLUT_CURSOR_INHERIT;
+    window->State.Modifiers = 0xffffffff;
+
+    /*
+     * 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, (parent != NULL) ? TRUE : FALSE );
+
+    /*
+     * Return a pointer to the newly created window
+     */
+    return( window );
+}
+
+/*
+ * This private function creates a menu and adds it to the menus list
+ */
+SFG_Menu* fgCreateMenu( FGCBmenu menuCallback )
+{
+    /*
+     * Have the menu object created
+     */
+    SFG_Menu* menu = calloc( sizeof(SFG_Menu), 1 );
+    int fakeArgc = 0;
+
+    /*
+     * If the freeglut internals haven't been initialized yet,
+     * do it now. Hack's idea courtesy of Chris Purnell...
+     */
+    if( !fgState.Time.Set )
+        glutInit( &fakeArgc, NULL );
+
+    /*
+     * Initialize the object properties:
+     */
+    menu->ID       = ++fgStructure.MenuID;
+    menu->Callback = menuCallback;
+
+    /*
+     * Initialize the entries list
+     */
+    fgListInit( &menu->Entries );
+
+    /*
+     * Add it to the menu structure hierarchy
+     */
+    fgListAppend( &fgStructure.Menus, &menu->Node );
+
+    /*
+     * Newly created menus implicitly become current ones
+     */
+    fgStructure.Menu = menu;
+
+    /*
+     * Return the result to the caller
+     */
+    return( menu );
+}
+
+/*
+ * Linked list of windows to destroy ... this is so we don't destroy a window from the middle of
+ * its callback.  Some C compilers take an extremely dim view of this.
+ */
+
+static SFG_WindowList* WindowsToDestroy = (SFG_WindowList*)NULL ;
+
+/*
+ * 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, GLboolean needToClose )
+{
+  SFG_WindowList *new_list_entry = (SFG_WindowList*)malloc ( sizeof(SFG_WindowList) ) ;
+  new_list_entry->window = window ;
+  new_list_entry->needToClose = needToClose ;
+  new_list_entry->next = WindowsToDestroy ;
+  WindowsToDestroy = new_list_entry ;
+
+  /*
+   * Check if the window is the current one...
+   */
+  if ( fgStructure.Window == window )
+    fgStructure.Window = NULL;
+
+  /*
+   * If the destroyed window has the highest window ID number, decrement the window ID number
+   */
+  if ( window->ID == fgStructure.WindowID ) fgStructure.WindowID-- ;
+
+  /*
+   * Check the execution state.  If this has been called from "glutDestroyWindow",
+   * a statement in that function will reset the "ExecState" after this function returns.
+   */
+  if ( fgState.ActionOnWindowClose != GLUT_ACTION_CONTINUE_EXECUTION )
+  {
+    /*
+     * Set the execution state flag to drop out of the main loop.
+     */
+    if ( fgState.ActionOnWindowClose == GLUT_ACTION_EXIT )
+      fgState.ExecState = GLUT_EXEC_STATE_STOP ;
+  }
+}
+
+/*
+ * Function to close down all the windows in the "WindowsToDestroy" list
+ */
+void fgCloseWindows ()
+{
+  SFG_WindowList *window_ptr = WindowsToDestroy ;
+  WindowsToDestroy = (SFG_WindowList*)NULL ;  /* In case the destroy callbacks cause more windows to be closed */
+
+  while ( window_ptr )
+  {
+    SFG_WindowList *next = window_ptr->next ;
+    fgDestroyWindow ( window_ptr->window, window_ptr->needToClose ) ;
+    free ( window_ptr ) ;
+    window_ptr = next ;
+
+    if ( !window_ptr )
+    {
+      window_ptr = WindowsToDestroy ;
+      WindowsToDestroy = (SFG_WindowList*)NULL ;
+    }
+  }
+}
+
+/*
+ * 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, GLboolean needToClose )
+{
+    SFG_Window* subWindow;
+
+    assert( window != NULL );
+    freeglut_assert_ready;
+
+    /*
+     * Does this window have any subwindows?
+     */
+    while ( (subWindow = window->Children.First) != NULL )
+    {
+        /*
+         * Destroy the first window in the list (possibly destroying
+         * its subwindows too). This is not very effective, but works
+         */
+        fgDestroyWindow( subWindow, needToClose );
+    }
+
+    /*
+     * If the programmer defined a destroy callback, call it
+     * A. Donev: But first make this the active window
+     */
+    if ( window->Callbacks.Destroy != NULL )
+    {
+      SFG_Window *activeWindow = fgStructure.Window ;
+      fgStructure.Window = window ;
+      window->Callbacks.Destroy () ;
+      fgStructure.Window = activeWindow ;
+    }
+
+    /*
+     * Now we should remove the reference to this window from its parent
+     */
+    if ( window->Parent != NULL )
+        fgListRemove( &window->Parent->Children, &window->Node );
+    else
+        fgListRemove( &fgStructure.Windows, &window->Node );
+
+    /*
+     * OK, this window seems disconnected from the structure enough
+     * in order to be closed without any bigger risks...
+     */
+    if( needToClose == TRUE )
+        fgCloseWindow( window );
+
+    /*
+     * Finally, we can delete the window's object. It hopefully does
+     * have everything inside it freed and we do not have to care...
+     */
+    free( window );
+}
+
+/*
+ * 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 if the menu is attached to the current window,
+     * if so, have it detached (by overwriting with a NULL):
+     */
+    for( i=0; i<3; i++ )
+    {
+        if( window->Menu[ i ] == menu )
+            window->Menu[ i ] = NULL;
+    }
+
+    /*
+     * Call this function for all of the window's children recursively:
+     */
+    for( subWindow = window->Children.First; subWindow;
+         subWindow = 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 = from->Entries.First; entry; entry = 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;
+  SFG_MenuEntry *entry;
+
+  assert( menu != NULL );
+  freeglut_assert_ready;
+
+  /*
+   * First of all, have all references to this menu removed from all windows:
+   */
+  for( window = fgStructure.Windows.First; window; window = window->Node.Next )
+  {
+    fghRemoveMenuFromWindow( window, menu );
+  }
+
+  /*
+   * Now proceed with removing menu entries that lead to this menu
+   */
+  for( from = fgStructure.Menus.First; from; from = 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 != NULL )
+  {
+    SFG_Menu *activeMenu=fgStructure.Menu;
+    fgStructure.Menu = menu;    
+    menu->Destroy () ;  
+    fgStructure.Menu = activeMenu;     
+  }        
+
+  /*
+   * Now we are pretty sure the menu is not used anywhere
+   * and that we can remove all of its entries
+   */
+  while( (entry = menu->Entries.First) != NULL )
+  {
+    fgListRemove(&menu->Entries, &entry->Node);
+
+    /*
+     * There might be a string allocated, have it freed:
+     */
+    free( entry->Text );
+
+    /*
+     * Deallocate the entry itself:
+     */
+    free( entry );
+  }
+
+  /*
+   * Remove the menu from the menus list
+   */
+  fgListRemove( &fgStructure.Menus, &menu->Node );
+
+  /*
+   * If that menu was the current one...
+   */
+  if( fgStructure.Menu == menu )
+    fgStructure.Menu = NULL;
+
+  /*
+   * Have the menu structure freed
+   */
+  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);
+}
+
+/*
+ * This function is automatically called on glutMainLoop() return. It should deallocate 
+ * and destroy all remnants of previous glutInit()-enforced structure initialization...
+ */
+void fgDestroyStructure( void )
+{
+  SFG_Window *window;
+  SFG_Menu *menu;
+
+  /*
+   * Just make sure we are not called in vain...
+   */
+  freeglut_assert_ready;
+
+  /*
+   * Make sure all windows and menus have been deallocated
+   */
+  while( (window = fgStructure.Windows.First) != NULL )
+    fgDestroyWindow( window, TRUE );
+
+  while( (menu = fgStructure.Menus.First) != NULL )
+    fgDestroyMenu( menu );
+}
+
+/*
+ * Helper function to enumerate through all registered top-level windows
+ */
+void fgEnumWindows( FGCBenumerator enumCallback, SFG_Enumerator* enumerator )
+{
+  SFG_Window *window;
+
+  assert( (enumCallback != NULL) && (enumerator != NULL) );
+  freeglut_assert_ready;
+
+  /*
+   * Check every of the top-level windows
+   */
+  for( window = fgStructure.Windows.First; window;
+       window = window->Node.Next )
+  {
+    /*
+     * Execute the callback...
+     */
+    enumCallback( window, enumerator );
+
+    /*
+     * If it has been marked as 'found', stop searching
+     */
+    if( enumerator->found == TRUE )
+      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;
+
+  assert( (enumCallback != NULL) && (enumerator != NULL) );
+  freeglut_assert_ready;
+
+  /*
+   * Check every of the window's children:
+   */
+  for( child = window->Children.First; child; child = child->Node.Next )
+  {
+    /*
+     * Execute the callback...
+     */
+    enumCallback( child, enumerator );
+
+    /*
+     * If it has been marked as 'found', stop searching
+     */
+    if( enumerator->found == TRUE )
+      return;
+  }
+}
+
+/*
+ * A static helper function to look for a window given its handle
+ */
+static void fghcbWindowByHandle( SFG_Window *window, SFG_Enumerator *enumerator )
+{
+    /*
+     * Make sure we do not overwrite our precious results...
+     */
+    freeglut_return_if_fail( enumerator->found == FALSE );
+
+#if TARGET_HOST_UNIX_X11
+    #define WBHANDLE (Window)
+#elif TARGET_HOST_WIN32
+    #define WBHANDLE (HWND)
+#endif
+
+    /*
+     * Check the window's handle. Hope this works. Looks ugly. That's for sure.
+     */
+    if( window->Window.Handle == WBHANDLE (enumerator->data) )
+    {
+        enumerator->found = TRUE;
+        enumerator->data = window;
+
+        return;
+    }
+
+    /*
+     * Otherwise, check this window's children
+     */
+    fgEnumSubWindows( window, fghcbWindowByHandle, enumerator );
+
+#undef WBHANDLE
+}
+
+/*
+ * 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
+#if TARGET_HOST_UNIX_X11
+( Window hWindow )
+#elif TARGET_HOST_WIN32
+( HWND hWindow )
+#endif
+{
+    SFG_Enumerator enumerator;
+
+    /*
+     * This is easy and makes use of the windows enumeration defined above
+     */
+    enumerator.found = FALSE;
+    enumerator.data = (void *)hWindow;
+
+    /*
+     * Start the enumeration now:
+     */
+    fgEnumWindows( fghcbWindowByHandle, &enumerator );
+
+    /*
+     * Check if the window has been found or not:
+     */
+    if( enumerator.found == TRUE )
+        return( (SFG_Window *) enumerator.data );
+
+    /*
+     * Otherwise return NULL to mark the failure
+     */
+    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...
+     */
+    freeglut_return_if_fail( enumerator->found == FALSE );
+
+    /*
+     * Check the window's handle. Hope this works. Looks ugly. That's for sure.
+     */
+    if( window->ID == (int) (enumerator->data) )
+    {
+        enumerator->found = TRUE;
+        enumerator->data = window;
+
+        return;
+    }
+
+    /*
+     * Otherwise, check 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 = FALSE;
+    enumerator.data = (void *) windowID;
+
+    /*
+     * Start the enumeration now:
+     */
+    fgEnumWindows( fghcbWindowByID, &enumerator );
+
+    /*
+     * Check if the window has been found or not:
+     */
+    if( enumerator.found == TRUE )
+        return( (SFG_Window *) enumerator.data );
+
+    /*
+     * Otherwise return NULL to mark the failure
+     */
+    return( NULL );
+}
+
+/*
+ * Looks up a menu given its ID. This is easier that fgWindowByXXX
+ * as all menus are placed in a single doubly linked list...
+ */
+SFG_Menu* fgMenuByID( int menuID )
+{
+    SFG_Menu *menu = NULL;
+
+    freeglut_assert_ready;
+
+    /*
+     * It's enough to check all entries in fgStructure.Menus...
+     */
+    for( menu = fgStructure.Menus.First; menu; menu = menu->Node.Next )
+    {
+        /*
+         * Does the ID number match?
+         */
+        if( menu->ID == menuID )
+            return( menu );
+    }
+
+    /*
+     * We have not found the requested menu ID
+     */
+    return( NULL );
+}
+
+/*
+ * List functions...
+ */
+void fgListInit(SFG_List *list)
+{
+    list->First = NULL;
+    list->Last = NULL;
+}
+
+void fgListAppend(SFG_List *list, SFG_Node *node)
+{
+    SFG_Node *ln;
+
+    if ( (ln = list->Last) != NULL )
+    {
+        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)
+{
+    SFG_Node *ln;
+
+    if ( (ln = node->Next) != NULL )
+        ln->Prev = node->Prev;
+    if ( (ln = node->Prev) != NULL )
+        ln->Next = node->Next;
+    if ( (ln = list->First) == node )
+        list->First = node->Next;
+    if ( (ln = list->Last) == node )
+        list->Last = node->Prev;
+}
+
+int fgListLength(SFG_List *list)
+{
+    SFG_Node *node;
+    int length = 0;
+
+    for( node = list->First; node; node = node->Next )
+        ++length;
+
+    return( length );
+}
+
+/*** END OF FILE ***/
diff --git a/src/freeglut_teapot.c b/src/freeglut_teapot.c
new file mode 100644 (file)
index 0000000..0a3930e
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-teapot"
+
+#include "../include/GL/freeglut.h"
+#include "freeglut_internal.h"
+
+/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
+
+/*
+ * Rim, body, lid, and bottom data must be reflected in x and y;
+ * handle and spout data across the y axis only.
+ */
+static int patchdata[][16] =
+{
+    { 102, 103, 104, 105,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15 }, /* rim    */
+    {  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27 }, /* body   */
+    {  24,  25,  26,  27,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40 },
+    {  96,  96,  96,  96,  97,  98,  99, 100, 101, 101, 101, 101,   0,   1,   2,   3 }, /* lid    */
+    {   0,   1,   2,   3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117 },
+    { 118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120,  40,  39,  38,  37 }, /* bottom */
+    {  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56 }, /* handle */
+    {  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  28,  65,  66,  67 },
+    {  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83 }, /* spout  */
+    {  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95 }
+};
+
+static double cpdata[][3] =
+{
+    {0.2, 0, 2.7}, {0.2, -0.112, 2.7}, {0.112, -0.2, 2.7}, {0,
+    -0.2, 2.7}, {1.3375, 0, 2.53125}, {1.3375, -0.749, 2.53125},
+    {0.749, -1.3375, 2.53125}, {0, -1.3375, 2.53125}, {1.4375,
+    0, 2.53125}, {1.4375, -0.805, 2.53125}, {0.805, -1.4375,
+    2.53125}, {0, -1.4375, 2.53125}, {1.5, 0, 2.4}, {1.5, -0.84,
+    2.4}, {0.84, -1.5, 2.4}, {0, -1.5, 2.4}, {1.75, 0, 1.875},
+    {1.75, -0.98, 1.875}, {0.98, -1.75, 1.875}, {0, -1.75,
+    1.875}, {2, 0, 1.35}, {2, -1.12, 1.35}, {1.12, -2, 1.35},
+    {0, -2, 1.35}, {2, 0, 0.9}, {2, -1.12, 0.9}, {1.12, -2,
+    0.9}, {0, -2, 0.9}, {-2, 0, 0.9}, {2, 0, 0.45}, {2, -1.12,
+    0.45}, {1.12, -2, 0.45}, {0, -2, 0.45}, {1.5, 0, 0.225},
+    {1.5, -0.84, 0.225}, {0.84, -1.5, 0.225}, {0, -1.5, 0.225},
+    {1.5, 0, 0.15}, {1.5, -0.84, 0.15}, {0.84, -1.5, 0.15}, {0,
+    -1.5, 0.15}, {-1.6, 0, 2.025}, {-1.6, -0.3, 2.025}, {-1.5,
+    -0.3, 2.25}, {-1.5, 0, 2.25}, {-2.3, 0, 2.025}, {-2.3, -0.3,
+    2.025}, {-2.5, -0.3, 2.25}, {-2.5, 0, 2.25}, {-2.7, 0,
+    2.025}, {-2.7, -0.3, 2.025}, {-3, -0.3, 2.25}, {-3, 0,
+    2.25}, {-2.7, 0, 1.8}, {-2.7, -0.3, 1.8}, {-3, -0.3, 1.8},
+    {-3, 0, 1.8}, {-2.7, 0, 1.575}, {-2.7, -0.3, 1.575}, {-3,
+    -0.3, 1.35}, {-3, 0, 1.35}, {-2.5, 0, 1.125}, {-2.5, -0.3,
+    1.125}, {-2.65, -0.3, 0.9375}, {-2.65, 0, 0.9375}, {-2,
+    -0.3, 0.9}, {-1.9, -0.3, 0.6}, {-1.9, 0, 0.6}, {1.7, 0,
+    1.425}, {1.7, -0.66, 1.425}, {1.7, -0.66, 0.6}, {1.7, 0,
+    0.6}, {2.6, 0, 1.425}, {2.6, -0.66, 1.425}, {3.1, -0.66,
+    0.825}, {3.1, 0, 0.825}, {2.3, 0, 2.1}, {2.3, -0.25, 2.1},
+    {2.4, -0.25, 2.025}, {2.4, 0, 2.025}, {2.7, 0, 2.4}, {2.7,
+    -0.25, 2.4}, {3.3, -0.25, 2.4}, {3.3, 0, 2.4}, {2.8, 0,
+    2.475}, {2.8, -0.25, 2.475}, {3.525, -0.25, 2.49375},
+    {3.525, 0, 2.49375}, {2.9, 0, 2.475}, {2.9, -0.15, 2.475},
+    {3.45, -0.15, 2.5125}, {3.45, 0, 2.5125}, {2.8, 0, 2.4},
+    {2.8, -0.15, 2.4}, {3.2, -0.15, 2.4}, {3.2, 0, 2.4}, {0, 0,
+    3.15}, {0.8, 0, 3.15}, {0.8, -0.45, 3.15}, {0.45, -0.8,
+    3.15}, {0, -0.8, 3.15}, {0, 0, 2.85}, {1.4, 0, 2.4}, {1.4,
+    -0.784, 2.4}, {0.784, -1.4, 2.4}, {0, -1.4, 2.4}, {0.4, 0,
+    2.55}, {0.4, -0.224, 2.55}, {0.224, -0.4, 2.55}, {0, -0.4,
+    2.55}, {1.3, 0, 2.55}, {1.3, -0.728, 2.55}, {0.728, -1.3,
+    2.55}, {0, -1.3, 2.55}, {1.3, 0, 2.4}, {1.3, -0.728, 2.4},
+    {0.728, -1.3, 2.4}, {0, -1.3, 2.4}, {0, 0, 0}, {1.425,
+    -0.798, 0}, {1.5, 0, 0.075}, {1.425, 0, 0}, {0.798, -1.425,
+    0}, {0, -1.5, 0.075}, {0, -1.425, 0}, {1.5, -0.84, 0.075},
+    {0.84, -1.5, 0.075}
+};
+
+static double tex[2][2][2] =
+{
+    { {0.0, 0.0}, {1.0, 0.0} },
+    { {0.0, 1.0}, {1.0, 1.0} }
+};
+
+static void teapot( GLint grid, GLdouble scale, GLenum type )
+{
+    double p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3];
+    long i, j, k, l;
+
+    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);
+
+    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);
+      }
+    }
+
+    glPopMatrix();
+    glPopAttrib();
+}
+
+
+/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
+
+/*
+ * Renders a beautiful wired teapot...
+ */
+void FGAPIENTRY glutWireTeapot( GLdouble size )
+{
+    /*
+     * We will use the general teapot rendering code
+     */
+    teapot( 10, size, GL_LINE );
+}
+
+/*
+ * Renders a beautiful filled teapot...
+ */
+void FGAPIENTRY glutSolidTeapot( GLdouble size )
+{
+    /*
+     * We will use the general teapot rendering code
+     */
+    teapot( 7, size, GL_FILL );
+}
+
+/*** END OF FILE ***/
+
+
+
+
+
diff --git a/src/freeglut_videoresize.c b/src/freeglut_videoresize.c
new file mode 100644 (file)
index 0000000..050dbe1
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-videoresize"
+
+#include "../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 ***/
+
+
+
+
+
+
+
diff --git a/src/freeglut_window.c b/src/freeglut_window.c
new file mode 100644 (file)
index 0000000..9e4a9e3
--- /dev/null
@@ -0,0 +1,1189 @@
+/*
+ * freeglut_window.c
+ *
+ * Window management 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define  G_LOG_DOMAIN  "freeglut-window"
+
+#include "../include/GL/freeglut.h"
+#include "freeglut_internal.h"
+
+/*
+ * TODO BEFORE THE STABLE RELEASE:
+ *
+ *  fgChooseVisual()        -- OK, but what about glutInitDisplayString()?
+ *  fgSetupPixelFormat      -- ignores the display mode settings
+ *  fgOpenWindow()          -- check the Win32 version, -iconic handling!
+ *  fgCloseWindow()         -- check the Win32 version
+ *  glutCreateWindow()      -- see what happens when default position and size is {-1,-1}
+ *  glutCreateSubWindow()   -- see what happens when default position and size is {-1,-1}
+ *  glutDestroyWindow()     -- check the Win32 version
+ *  glutSetWindow()         -- check the Win32 version
+ *  glutGetWindow()         -- OK
+ *  glutSetWindowTitle()    -- check the Win32 version
+ *  glutSetIconTitle()      -- check the Win32 version
+ *  glutShowWindow()        -- check the Win32 version
+ *  glutHideWindow()        -- check the Win32 version
+ *  glutIconifyWindow()     -- check the Win32 version
+ *  glutReshapeWindow()     -- check the Win32 version
+ *  glutPositionWindow()    -- check the Win32 version
+ *  glutPushWindow()        -- check the Win32 version
+ *  glutPopWindow()         -- check the Win32 version
+ */
+
+/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
+
+/*
+ * Chooses a visual basing on the current display mode settings
+ */
+#if TARGET_HOST_UNIX_X11
+XVisualInfo* fgChooseVisual( void )
+{
+    int bufferSize[] = { 16, 12, 8, 4, 2, 1 };
+    GLboolean wantIndexedMode = FALSE;
+    int attributes[ 32 ];
+    int where = 0;
+
+    /*
+     * First we have to process the display mode settings...
+     */
+#   define ATTRIB(a) attributes[where++]=a;
+
+    /*
+     * Decide if we want a true or indexed color visual:
+     */
+    if( !(fgState.DisplayMode & GLUT_INDEX) )
+    {
+        /*
+         * We are sure that there will be R, B and B components requested:
+         */
+        ATTRIB( GLX_RGBA       );
+        ATTRIB( GLX_RED_SIZE   ); ATTRIB( 1 );
+        ATTRIB( GLX_GREEN_SIZE ); ATTRIB( 1 );
+        ATTRIB( GLX_BLUE_SIZE  ); ATTRIB( 1 );
+
+        /*
+         * Check if the A component is required, too:
+         */
+        if( fgState.DisplayMode & GLUT_ALPHA )
+        {
+            ATTRIB( GLX_ALPHA_SIZE ); ATTRIB( 1 );
+        }
+    }
+    else
+    {
+        /*
+         * We've got an indexed color request
+         */
+        ATTRIB( GLX_BUFFER_SIZE ); ATTRIB( 8 );
+
+        /*
+         * Set the 'I want indexed mode' switch
+         */
+        wantIndexedMode = TRUE;
+    }
+
+    /*
+     * We can have double or single buffered contexts created
+     */
+    if( fgState.DisplayMode & GLUT_DOUBLE )
+    {
+        ATTRIB( GLX_DOUBLEBUFFER );
+    }
+
+    /*
+     * Stereoscopy seems a nice thing to have
+     */
+    if( fgState.DisplayMode & GLUT_STEREO )
+    {
+        ATTRIB( GLX_STEREO );
+    }
+
+    /*
+     * Depth buffer is almost always required
+     */
+    if( fgState.DisplayMode & GLUT_DEPTH )
+    {
+        ATTRIB( GLX_DEPTH_SIZE ); ATTRIB( 1 );
+    }
+
+    /*
+     * Stenciling support
+     */
+    if( fgState.DisplayMode & GLUT_STENCIL )
+    {
+        ATTRIB( GLX_STENCIL_SIZE ); ATTRIB( 1 );
+    }
+
+    /*
+     * And finally the accumulation buffers
+     */
+    if( fgState.DisplayMode & GLUT_ACCUM )
+    {
+        ATTRIB( GLX_ACCUM_RED_SIZE );   ATTRIB( 1 );
+        ATTRIB( GLX_ACCUM_GREEN_SIZE ); ATTRIB( 1 );
+        ATTRIB( GLX_ACCUM_BLUE_SIZE );  ATTRIB( 1 );
+
+        /*
+         * Check if the A component is required, too:
+         */
+        if( fgState.DisplayMode & GLUT_ALPHA )
+        {
+            ATTRIB( GLX_ACCUM_ALPHA_SIZE ); ATTRIB( 1 );
+        }
+    }
+
+    /*
+     * Push a null at the end of the list
+     */
+    ATTRIB( None );
+
+    /*
+     * OKi now, we've got two cases -- RGB(A) and index mode visuals
+     */
+    if( wantIndexedMode == FALSE )
+    {
+        /*
+         * The easier one. And more common, too.
+         */
+        return( glXChooseVisual( fgDisplay.Display, fgDisplay.Screen, attributes ) );
+    }
+    else
+    {
+        XVisualInfo* visualInfo;
+        int i;
+
+        /*
+         * In indexed mode, we need to check how many bits of depth can we achieve
+         */
+        for( i=0; i<6; i++ )
+        {
+
+            /*
+             * The GLX_BUFFER_SIZE value comes always first, so:
+             */
+            attributes[ 1 ] = bufferSize[ i ];
+
+            /*
+             * Check if such visual is possible
+             */
+            visualInfo = glXChooseVisual( fgDisplay.Display, fgDisplay.Screen, attributes );
+
+            /*
+             * The buffer size are sorted in descendant order, so choose the first:
+             */
+            if( visualInfo != NULL )
+                return( visualInfo );
+        }
+
+        /*
+         * If we are still here, it means that the visual info was not found
+         */
+        return( NULL );
+    }
+}
+#endif
+
+/*
+ * Setup the pixel format for a Win32 window
+ */
+#if TARGET_HOST_WIN32
+GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, unsigned char layer_type )
+{
+       PIXELFORMATDESCRIPTOR* ppfd, pfd;
+       int flags, pixelformat;
+
+       /*
+        * Check if the window seems valid
+        */
+       freeglut_return_val_if_fail( window != NULL, 0 );
+
+       /*
+        * The pixel format should allow us to draw to the window using OpenGL
+        */
+       flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
+       
+       /*
+        * It might be the case for us to use double buffering
+        */
+  if( fgState.DisplayMode & GLUT_DOUBLE )
+       flags |= PFD_DOUBLEBUFFER;
+
+  /*
+   * Specify which pixel format do we opt for...
+   */
+#      pragma message( "fgSetupPixelFormat(): there is still some work to do here!" )
+
+  pfd.nSize                            = sizeof(PIXELFORMATDESCRIPTOR);
+  pfd.nVersion                 = 1;
+  pfd.dwFlags                          = flags;
+  pfd.iPixelType                       = PFD_TYPE_RGBA;
+  pfd.cColorBits                       = 24;
+  pfd.cRedBits                 = 0;
+  pfd.cRedShift                        = 0;
+  pfd.cGreenBits                       = 0;
+  pfd.cGreenShift                      = 0;
+  pfd.cBlueBits                        = 0;
+  pfd.cBlueShift                       = 0;
+  pfd.cAlphaBits                       = 0;
+  pfd.cAlphaShift                      = 0;
+  pfd.cAccumBits                       = 0;
+  pfd.cAccumRedBits            = 0;
+  pfd.cAccumGreenBits          = 0;
+  pfd.cAccumBlueBits           = 0;
+  pfd.cAccumAlphaBits          = 0;
+#if 0
+  pfd.cDepthBits                       = 32;
+  pfd.cStencilBits             = 0;
+#else
+  pfd.cDepthBits                       = 24;
+  pfd.cStencilBits             = 8;
+#endif
+  pfd.cAuxBuffers                      = 0;
+  pfd.iLayerType                       = layer_type;
+  pfd.bReserved                        = 0;
+  pfd.dwLayerMask                      = 0;
+  pfd.dwVisibleMask            = 0;
+  pfd.dwDamageMask             = 0;
+
+  /*
+   * Fill in the color bits...
+   */
+  pfd.cColorBits = (BYTE) GetDeviceCaps( window->Window.Device, BITSPIXEL );
+  ppfd = &pfd;
+
+       /*
+        * Choose the pixel format that matches our demand
+        */
+  pixelformat = ChoosePixelFormat( window->Window.Device, ppfd );
+       if( pixelformat == 0 )
+               return( FALSE );
+
+       /*
+        * We might have been called to check if the pixel format exists only
+        */
+       if( checkOnly )
+               return( TRUE );
+
+       /*
+        * Finally, set the window's pixel format
+        */
+       return ( SetPixelFormat( window->Window.Device, pixelformat, ppfd ) ) ;
+}
+#endif
+
+/*
+ * Sets the OpenGL context and the fgStructure "Current Window" pointer to the window
+ * structure passed in.
+ */
+void fgSetWindow ( SFG_Window *window )
+{
+#if TARGET_HOST_UNIX_X11
+    /*
+        * Make the selected window's GLX context the current one
+     */
+    glXMakeCurrent(
+        fgDisplay.Display,
+        window->Window.Handle,
+        window->Window.Context
+    );
+
+#elif TARGET_HOST_WIN32
+       /*
+        * Release the previous' context's device context
+        */
+       if( fgStructure.Window != NULL )
+               ReleaseDC( fgStructure.Window->Window.Handle, fgStructure.Window->Window.Device );
+
+  if ( window )
+  {
+       /*
+          * We will care about releasing the device context later
+          */
+       window->Window.Device = GetDC( window->Window.Handle );
+
+       /*
+          * Set the new current context:
+          */
+       wglMakeCurrent( 
+               window->Window.Device, 
+                 window->Window.Context 
+       );
+  }
+#endif
+
+    /*
+     * Remember that we have changed the current window state
+     */
+    fgStructure.Window = window;
+}
+
+
+/*
+ * Opens a window. Requires a SFG_Window object created and attached
+ * to the freeglut structure. OpenGL context is created here.
+ */
+void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, int h, GLboolean gameMode, int isSubWindow )
+{
+#if TARGET_HOST_UNIX_X11
+    XSetWindowAttributes winAttr;
+    XTextProperty textProperty;
+    XSizeHints sizeHints;
+    XWMHints wmHints;
+    unsigned long mask;
+
+    freeglut_assert_ready;
+
+    /*
+     * Here we are upon the stage. Have the visual selected.
+     */
+    window->Window.VisualInfo = fgChooseVisual();
+    if ( ! window->Window.VisualInfo )
+    {
+      /*
+       * The "fgChooseVisual" returned a null meaning that the visual context is not available.
+       * Try a couple of variations to see if they will work.
+       */
+      if ( ! ( fgState.DisplayMode & GLUT_DOUBLE ) )
+      {
+        /*
+         * Single buffering--try it doubled
+         */
+        fgState.DisplayMode |= GLUT_DOUBLE ;
+        window->Window.VisualInfo = fgChooseVisual();
+      }
+
+      /*
+       * GLUT also checks for multi-sampling, but I don't see that anywhere else in FREEGLUT
+       * so I won't bother with it for the moment.
+       */
+    }
+
+    assert( window->Window.VisualInfo != NULL );
+
+    /*
+     * Have the windows attributes set
+     *
+     * HINT: the masks should be updated when adding/removing callbacks.
+     *       This might speed up message processing. Is that true?
+     */
+    winAttr.event_mask        = StructureNotifyMask | SubstructureNotifyMask | ExposureMask |
+                                ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyRelease |
+                                VisibilityChangeMask | EnterWindowMask | LeaveWindowMask |
+                                PointerMotionMask | ButtonMotionMask;
+    winAttr.background_pixmap = None;
+    winAttr.background_pixel  = 0;
+    winAttr.border_pixel      = 0;
+
+    /*
+     * The color map is required, too
+     */
+    winAttr.colormap = XCreateColormap(
+        fgDisplay.Display, fgDisplay.RootWindow,
+        window->Window.VisualInfo->visual, AllocNone
+    );
+
+    /*
+     * This tells the XCreateWindow() what attributes are we supplying it with
+     */
+    mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
+
+    /*
+     * Have the window created now
+     */
+    window->Window.Handle = XCreateWindow(
+        fgDisplay.Display,
+        window->Parent == NULL ? fgDisplay.RootWindow : window->Parent->Window.Handle,
+        x, y, w, h, 0,
+        window->Window.VisualInfo->depth, InputOutput,
+        window->Window.VisualInfo->visual, mask,
+        &winAttr
+    );
+
+    /*
+     * The GLX context creation, possibly trying the direct context rendering
+     */
+    window->Window.Context = glXCreateContext(
+        fgDisplay.Display, window->Window.VisualInfo,
+        NULL, fgState.ForceDirectContext | fgState.TryDirectContext
+    );
+
+    /*
+     * Make sure the context is direct when the user wants it forced
+     */
+    if( fgState.ForceDirectContext && !glXIsDirect( fgDisplay.Display, window->Window.Context ) )
+        fgError( "unable to force direct context rendering for window '%s'", title );
+
+    /*
+     * Set the new context as the current one. That's all about the window creation.
+     */
+    glXMakeCurrent(
+        fgDisplay.Display,
+        window->Window.Handle,
+        window->Window.Context
+    );
+
+    /*
+     * Assume the new window is visible by default
+     */
+    window->State.Visible = TRUE;
+
+    /*
+     * For the position and size hints -- make sure we are passing valid values
+     */
+    sizeHints.flags = 0;
+
+    if (fgState.Position.Use == TRUE) sizeHints.flags |= USPosition;
+    if (fgState.Size.Use     == TRUE) sizeHints.flags |= USSize;
+
+    /*
+     * Fill in the size hints values now (the x, y, width and height
+     * settings are obsolote, are there any more WMs that support them?)
+     */
+    sizeHints.x      = x; sizeHints.y      = y;
+    sizeHints.width  = w; sizeHints.height = h;
+
+    /*
+     * We can have forced all new windows start in iconified state:
+     */
+    wmHints.flags = StateHint;
+    wmHints.initial_state = (fgState.ForceIconic == FALSE) ? NormalState : IconicState;
+
+    /*
+     * Prepare the window and iconified window names...
+     */
+    XStringListToTextProperty( (char **) &title, 1, &textProperty );
+
+    /*
+     * Set the window's properties now
+     */
+    XSetWMProperties(
+        fgDisplay.Display,
+        window->Window.Handle,
+        &textProperty,
+        &textProperty,
+        0,
+        0,
+        &sizeHints,
+        &wmHints,
+        NULL
+    );
+
+    /*
+     * Make sure we are informed about the window deletion commands
+     */
+    XSetWMProtocols( fgDisplay.Display, window->Window.Handle, &fgDisplay.DeleteWindow, 1 );
+
+    /*
+     * Finally, have the window mapped to our display
+     */
+    XMapWindow( fgDisplay.Display, window->Window.Handle );
+
+    /*
+     * In game mode, move the viewport a bit to hide the decorations.
+     * This code depends on the XFree86 video mode extensions.
+     */
+    if( gameMode == TRUE )
+    {
+        /*
+         * This somehow fixes the glutGet() GLUT_WINDOW_X and GLUT_WINDOW_Y problem...
+         */
+        XMoveWindow( fgDisplay.Display, window->Window.Handle, x, y );
+
+#       ifdef X_XF86VidModeSetViewPort
+
+        /*
+         * Set the newly created window as the current one...
+         */
+        fgSetWindow( window );
+
+        /*
+         * Move the viewport a bit down and right from top-left corner to hide the decorations
+         */
+        XF86VidModeSetViewPort(
+            fgDisplay.Display,
+            fgDisplay.Screen,
+            glutGet( GLUT_WINDOW_X ),
+            glutGet( GLUT_WINDOW_Y )
+        );
+
+#       endif
+    }
+
+#elif TARGET_HOST_WIN32
+
+       WNDCLASS wc;
+       int flags;
+       ATOM atom;
+
+    freeglut_assert_ready;
+
+       /*
+        * Grab the window class we have registered on glutInit():
+        */
+       atom = GetClassInfo( fgDisplay.Instance, "FREEGLUT", &wc );
+       assert( atom != 0 );
+
+    if( gameMode == FALSE )
+    {
+      if ( !isSubWindow )
+      {
+        /*
+         * Update the window dimensions, taking account of window decorations.
+         * "freeglut" is to create the window with the outside of its border at (x,y)
+         * and with dimensions (w,h).
+         */
+               w += (GetSystemMetrics( SM_CXSIZEFRAME ) )*2;
+               h += (GetSystemMetrics( SM_CYSIZEFRAME ) )*2 + GetSystemMetrics( SM_CYCAPTION );
+      }
+
+      /*
+            * Check if the user wants us to use the default position/size
+            */
+           if( fgState.Position.Use == FALSE ) { x = CW_USEDEFAULT; y = CW_USEDEFAULT; }
+           if( fgState.Size    .Use == FALSE ) { w = CW_USEDEFAULT; h = CW_USEDEFAULT; }
+
+           /*
+            * There's a small difference between creating the top, child and game mode windows
+            */
+           flags = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
+
+           if( window->Parent == NULL )
+                   flags |= WS_OVERLAPPEDWINDOW;
+           else
+                   flags |= WS_CHILD;
+    }
+    else
+    {
+        /*
+         * In game mode, the story is a little bit different...
+         */
+        assert( window->Parent == NULL );
+
+        /*
+         * Set the window creation flags appropriately to make the window entirely visible:
+         */
+        flags = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE;
+    }
+
+    /*
+     * Create the window now, passing the freeglut window structure as the parameter
+     */
+       window->Window.Handle = CreateWindow( 
+               "FREEGLUT",
+        title,
+               flags,
+        x, y, w, h,
+               (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle,
+               (HMENU) NULL,
+               fgDisplay.Instance,
+               (LPVOID) window
+       );
+
+       /*
+     * Make sure window was created
+     */
+       assert( window->Window.Handle != NULL );
+
+    /*
+     * Show and update the main window. Hide the mouse cursor.
+     */
+    ShowWindow( window->Window.Handle, fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW );
+    UpdateWindow( window->Window.Handle );
+    ShowCursor( TRUE );
+
+#endif
+
+    /*
+     * Save the window's single- or double-buffering state
+     */
+    window->Window.DoubleBuffered = ( fgState.DisplayMode & GLUT_DOUBLE ) ? 1 : 0 ;
+
+    /*
+     * If it's not double-buffered, make sure the rendering is done to the front buffer.
+     */
+    if ( ! window->Window.DoubleBuffered )
+    {
+      glDrawBuffer ( GL_FRONT ) ;
+      glReadBuffer ( GL_FRONT ) ;
+    }
+
+    /*
+     * Set the newly created window as the current one
+     */
+    fgSetWindow( window );
+}
+
+/*
+ * Closes a window, destroying the frame and OpenGL context
+ */
+void fgCloseWindow( SFG_Window* window )
+{
+    freeglut_assert_ready;
+
+#if TARGET_HOST_UNIX_X11
+    /*
+     * As easy as kill bunnies with axes. Destroy the context first:
+     */
+    glXDestroyContext( fgDisplay.Display, window->Window.Context );
+
+    /*
+     * Then have the window killed:
+     */
+    XDestroyWindow( fgDisplay.Display, window->Window.Handle );
+
+    /*
+     * Finally, flush the rests down the stream
+     */
+    XFlush( fgDisplay.Display );
+
+#elif TARGET_HOST_WIN32
+       /*
+        * Send the WM_CLOSE message to the window now
+        */
+       SendMessage( 
+               window->Window.Handle,
+               WM_CLOSE,
+               0,
+               0
+       );
+
+#endif
+}
+
+
+/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
+
+/*
+ * Creates a new top-level freeglut window
+ */
+int FGAPIENTRY glutCreateWindow( const char* title )
+{
+    /*
+     * Create a new window and return its unique ID number
+     */
+    return( fgCreateWindow( NULL, title, fgState.Position.X, fgState.Position.Y,
+                            fgState.Size.X, fgState.Size.Y, FALSE )->ID );
+}
+
+/*
+ * This function creates a sub window.
+ */
+int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h )
+{
+    SFG_Window* window = NULL;
+    SFG_Window* parent = NULL;
+
+    freeglut_assert_ready;
+
+    /*
+     * Find a parent to the newly created window...
+     */
+    parent = fgWindowByID( parentID );
+
+    /*
+     * Fail if the parent has not been found
+     */
+    freeglut_return_val_if_fail( parent != NULL, 0 );
+
+    /*
+     * Create the new window
+     */
+    window = fgCreateWindow( parent, "", x, y, w, h, FALSE );
+
+    /*
+     * Return the new window's ID
+     */
+    return( window->ID );
+}
+
+/*
+ * Destroys a window and all of its subwindows
+ */
+void FGAPIENTRY glutDestroyWindow( int windowID )
+{
+  fgExecutionState ExecState = fgState.ExecState ;
+
+  /*
+   * Grab the freeglut window pointer from the structure
+   */
+  SFG_Window* window = fgWindowByID( windowID );
+  freeglut_return_if_fail( window != NULL );
+
+  /*
+   * There is a function that performs all needed steps
+   * defined in freeglut_structure.c. Let's use it:
+   */
+  fgAddToWindowDestroyList( window, TRUE );
+
+  /*
+   * Since the "fgAddToWindowDestroyList" function could easily have set the "ExecState"
+   * to stop, let's set it back to what it was.
+   */
+  fgState.ExecState = ExecState ;
+}
+
+/*
+ * This function selects the current window
+ */
+void FGAPIENTRY glutSetWindow( int ID )
+{
+    SFG_Window* window = NULL;
+
+    /*
+     * Make sure we don't get called too early
+     */
+    freeglut_assert_ready;
+
+    /*
+     * Be wise. Be wise. Be wise. Be quick.
+     */
+    if( fgStructure.Window != NULL )
+        if( fgStructure.Window->ID == ID )
+            return;
+
+    /*
+     * Now we are sure there is sense in looking for the window
+     */
+    window = fgWindowByID( ID );
+
+    /*
+     * In the case of an utter failure...
+     */
+    if( window == NULL )
+    {
+        /*
+         * ...issue a warning message and keep rolling on
+         */
+        fgWarning( "glutSetWindow(): window ID %i not found!", ID );
+        return;
+    }
+
+    fgSetWindow ( window ) ;
+}
+
+/*
+ * This function returns the ID number of the current window, 0 if none exists
+ */
+int FGAPIENTRY glutGetWindow( void )
+{
+    freeglut_assert_ready;
+
+    /*
+     * Do we have a current window selected?
+     */
+    if( fgStructure.Window == NULL )
+    {
+        /*
+         * Nope. Return zero to mark the state.
+         */
+        return( 0 );
+    }
+
+    /*
+     * Otherwise, return the ID of the current window
+     */
+    return( fgStructure.Window->ID );
+}
+
+/*
+ * This function makes the current window visible
+ */
+void FGAPIENTRY glutShowWindow( void )
+{
+    freeglut_assert_ready; freeglut_assert_window;
+
+#if TARGET_HOST_UNIX_X11
+    /*
+     * Showing the window is done via mapping under X
+     */
+    XMapWindow( fgDisplay.Display, fgStructure.Window->Window.Handle );
+    XFlush( fgDisplay.Display );
+
+#elif TARGET_HOST_WIN32
+       /*
+        * Restore the window's originial position and size
+        */
+       ShowWindow( fgStructure.Window->Window.Handle, SW_SHOW );
+
+#endif
+}
+
+/*
+ * This function hides the current window
+ */
+void FGAPIENTRY glutHideWindow( void )
+{
+    freeglut_assert_ready; freeglut_assert_window;
+
+#if TARGET_HOST_UNIX_X11
+    /*
+     * The way we hide a window depends on if we're dealing
+     * with a top-level or children one...
+     */
+    if( fgStructure.Window->Parent == NULL )
+    {
+        /*
+         * This is a top-level window
+         */
+        XWithdrawWindow( fgDisplay.Display, fgStructure.Window->Window.Handle, fgDisplay.Screen );
+    }
+    else
+    {
+        /*
+         * Nope, it's a child window
+         */
+        XUnmapWindow( fgDisplay.Display, fgStructure.Window->Window.Handle );
+    }
+
+    /*
+     * Flush the X state now
+     */
+    XFlush( fgDisplay.Display );
+
+#elif TARGET_HOST_WIN32
+       /*
+        * Hide the window
+        */
+       ShowWindow( fgStructure.Window->Window.Handle, SW_HIDE );
+
+#endif
+}
+
+/*
+ * Iconify the current window (top-level windows only)
+ */
+void FGAPIENTRY glutIconifyWindow( void )
+{
+    freeglut_assert_ready; freeglut_assert_window;
+
+#if TARGET_HOST_UNIX_X11
+    /*
+     * Iconify the window and flush the X state
+     */
+    XIconifyWindow( fgDisplay.Display, fgStructure.Window->Window.Handle, fgDisplay.Screen );
+    XFlush( fgDisplay.Display );
+
+#elif TARGET_HOST_WIN32
+       /*
+        * Minimize the current window (this should be the same as X window iconifying)
+        */
+       ShowWindow( fgStructure.Window->Window.Handle, SW_MINIMIZE );
+
+#endif
+}
+
+/*
+ * Set the current window's title
+ */
+void FGAPIENTRY glutSetWindowTitle( const char* title )
+{
+       freeglut_assert_ready; freeglut_assert_window;
+
+    /*
+     * Works only for top-level windows
+     */
+    if( fgStructure.Window->Parent != NULL )
+        return;
+
+#if TARGET_HOST_UNIX_X11
+       {
+               XTextProperty text;
+
+               /*
+                * Prepare the text properties
+                */
+               text.value = (unsigned char *) title;
+               text.encoding = XA_STRING;
+               text.format = 8;
+               text.nitems = strlen( title );
+
+               /*
+                * Set the title now
+                */
+               XSetWMName(
+                       fgDisplay.Display,
+                       fgStructure.Window->Window.Handle,
+                       &text
+               );
+
+               /*
+                * Have the X display state flushed
+                */
+               XFlush( fgDisplay.Display );
+       }
+
+#elif TARGET_HOST_WIN32
+       /*
+        * This seems to be a bit easier under Win32
+        */
+       SetWindowText( fgStructure.Window->Window.Handle, title );
+
+#endif
+}
+
+/*
+ * Set the current window's iconified title
+ */
+void FGAPIENTRY glutSetIconTitle( const char* title )
+{
+    freeglut_assert_ready; freeglut_assert_window;
+
+    /*
+     * Works only for top-level windows
+     */
+    if( fgStructure.Window->Parent != NULL )
+        return;
+
+#if TARGET_HOST_UNIX_X11
+       {
+               XTextProperty text;
+
+               /*
+                * Prepare the text properties
+                */
+               text.value = (unsigned char *) title;
+               text.encoding = XA_STRING;
+               text.format = 8;
+               text.nitems = strlen( title );
+
+               /*
+                * Set the title now
+                */
+               XSetWMIconName(
+                       fgDisplay.Display,
+                       fgStructure.Window->Window.Handle,
+                       &text
+               );
+
+               /*
+                * Have the X display state flushed
+                */
+               XFlush( fgDisplay.Display );
+       }
+
+#elif TARGET_HOST_WIN32
+       /*
+        * This seems to be a bit easier under Win32
+        */
+       SetWindowText( fgStructure.Window->Window.Handle, title );
+
+#endif
+}
+
+/*
+ * Change the current window's size
+ */
+void FGAPIENTRY glutReshapeWindow( int width, int height )
+{
+    freeglut_assert_ready; freeglut_assert_window;
+
+#if TARGET_HOST_UNIX_X11
+    /*
+     * Resize the window and flush the X state
+     */
+    XResizeWindow( fgDisplay.Display, fgStructure.Window->Window.Handle, width, height );
+    XFlush( fgDisplay.Display );
+
+#elif TARGET_HOST_WIN32
+       {
+               RECT winRect;
+    int x, y ;
+
+               /*
+                * First off, grab the current window's position
+                */
+               GetWindowRect( fgStructure.Window->Window.Handle, &winRect );
+    x = winRect.left ;
+    y = winRect.top ;
+
+    if ( fgStructure.Window->Parent == NULL )  /* If this is not a subwindow ... */
+    {
+      /*
+       * Adjust the size of the window to allow for the size of the frame
+       */
+               width += GetSystemMetrics( SM_CXSIZEFRAME ) * 2;
+               height += GetSystemMetrics( SM_CYSIZEFRAME ) * 2 + GetSystemMetrics( SM_CYCAPTION );
+    }
+    else  /* This is a subwindow, get the parent window's position and subtract it off */
+    {
+      GetWindowRect ( fgStructure.Window->Parent->Window.Handle, &winRect ) ;
+      x -= winRect.left + GetSystemMetrics( SM_CXSIZEFRAME ) ;
+      y -= winRect.top + GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION ) ;
+    }
+
+               /*
+                * Resize the window, forcing a redraw to happen
+                */
+               MoveWindow(
+                       fgStructure.Window->Window.Handle,
+                       x,
+                       y,
+                       width,
+                       height,
+                       TRUE
+               );
+       }
+#endif
+}
+
+/*
+ * Change the current window's position
+ */
+void FGAPIENTRY glutPositionWindow( int x, int y )
+{
+    freeglut_assert_ready; freeglut_assert_window;
+
+#if TARGET_HOST_UNIX_X11
+    /*
+     * Reposition the window and flush the X state
+     */
+    XMoveWindow( fgDisplay.Display, fgStructure.Window->Window.Handle, x, y );
+    XFlush( fgDisplay.Display );
+
+#elif TARGET_HOST_WIN32
+       {
+               RECT winRect;
+
+               /*
+                * First off, grab the current window's position
+                */
+               GetWindowRect( fgStructure.Window->Window.Handle, &winRect );
+
+    /*
+                * Reposition the window, forcing a redraw to happen
+                */
+               MoveWindow(
+                       fgStructure.Window->Window.Handle,
+                       x,
+                       y,
+                       winRect.right - winRect.left,
+                       winRect.bottom - winRect.top,
+                       TRUE
+               );
+       }
+
+#endif
+}
+
+/*
+ * Lowers the current window (by Z order change)
+ */
+void FGAPIENTRY glutPushWindow( void )
+{
+    freeglut_assert_ready; freeglut_assert_window;
+
+#if TARGET_HOST_UNIX_X11
+    /*
+     * Lower the current window
+     */
+    XLowerWindow( fgDisplay.Display, fgStructure.Window->Window.Handle );
+
+#elif TARGET_HOST_WIN32
+       /*
+        * Set the new window's Z position, not affecting the rest of the settings:
+        */
+       SetWindowPos(
+               fgStructure.Window->Window.Handle,
+               HWND_BOTTOM,
+               0, 0, 0, 0,
+               SWP_NOSIZE | SWP_NOMOVE
+       );
+
+#endif
+}
+
+/*
+ * Raises the current window (by Z order change)
+ */
+void FGAPIENTRY glutPopWindow( void )
+{
+    freeglut_assert_ready; freeglut_assert_window;
+
+#if TARGET_HOST_UNIX_X11
+    /*
+     * Raise the current window
+     */
+    XRaiseWindow( fgDisplay.Display, fgStructure.Window->Window.Handle );
+
+#elif TARGET_HOST_WIN32
+       /*
+        * Set the new window's Z position, not affecting the rest of the settings:
+        */
+       SetWindowPos(
+               fgStructure.Window->Window.Handle,
+               HWND_TOP,
+               0, 0, 0, 0,
+               SWP_NOSIZE | SWP_NOMOVE
+       );
+
+#endif
+}
+
+/*
+ * Resize the current window so that it fits the whole screen
+ */
+void FGAPIENTRY glutFullScreen( void )
+{
+    freeglut_assert_ready; freeglut_assert_window;
+
+    /*
+     * Just have the window repositioned and resized
+     */
+    glutPositionWindow( 0, 0 );
+
+    glutReshapeWindow(
+        fgDisplay.ScreenWidth,
+        fgDisplay.ScreenHeight
+    );
+}
+
+/*
+ * A.Donev: Set and retrieve the window's user data
+ */
+void* FGAPIENTRY glutGetWindowData( void )
+{
+   return(fgStructure.Window->UserData);
+}
+
+void FGAPIENTRY glutSetWindowData(void* data)
+{
+  fgStructure.Window->UserData=data;
+}
+
+/*** END OF FILE ***/
+
+
+
+
+
+
+
+
+
diff --git a/src/freeglutdll.def b/src/freeglutdll.def
new file mode 100644 (file)
index 0000000..89155b6
--- /dev/null
@@ -0,0 +1,132 @@
+LIBRARY freeglutdll
+DESCRIPTION "Freeglut OpenGL Utility Toolkit"
+VERSION 1.3
+EXPORTS
+       glutInit
+       glutInitWindowPosition
+       glutInitWindowSize
+       glutInitDisplayMode
+       glutInitDisplayString
+       glutMainLoop
+       glutMainLoopEvent
+       glutLeaveMainLoop
+       glutCreateWindow
+       glutCreateSubWindow
+       glutDestroyWindow
+       glutSetWindow
+       glutGetWindow
+       glutSetWindowTitle
+       glutSetIconTitle
+       glutReshapeWindow
+       glutPositionWindow
+       glutShowWindow
+       glutHideWindow
+       glutIconifyWindow
+       glutPushWindow
+       glutPopWindow
+       glutFullScreen
+       glutPostWindowRedisplay
+       glutPostRedisplay
+       glutSwapBuffers
+       glutWarpPointer
+       glutSetCursor
+       glutEstablishOverlay
+       glutRemoveOverlay
+       glutUseLayer
+       glutPostOverlayRedisplay
+       glutPostWindowOverlayRedisplay
+       glutShowOverlay
+       glutHideOverlay
+       glutCreateMenu
+       glutDestroyMenu
+       glutGetMenu
+       glutSetMenu
+       glutAddMenuEntry
+       glutAddSubMenu
+       glutChangeToMenuEntry
+       glutChangeToSubMenu
+       glutRemoveMenuItem
+       glutAttachMenu
+       glutDetachMenu
+       glutTimerFunc
+       glutIdleFunc
+       glutKeyboardFunc
+       glutSpecialFunc
+       glutReshapeFunc
+       glutVisibilityFunc
+       glutDisplayFunc
+       glutMouseFunc
+       glutMotionFunc
+       glutPassiveMotionFunc
+       glutEntryFunc
+       glutCloseFunc
+       glutWMCloseFunc
+       glutKeyboardUpFunc
+       glutSpecialUpFunc
+       glutJoystickFunc
+       glutMenuStateFunc
+       glutMenuStatusFunc
+       glutOverlayDisplayFunc
+       glutWindowStatusFunc
+       glutSpaceballMotionFunc
+       glutSpaceballRotateFunc
+       glutSpaceballButtonFunc
+       glutButtonBoxFunc
+       glutDialsFunc
+       glutTabletMotionFunc
+       glutTabletButtonFunc
+       glutSetOption
+       glutGet
+       glutDeviceGet
+       glutGetModifiers
+       glutLayerGet
+       glutBitmapCharacter
+       glutBitmapWidth
+       glutStrokeCharacter
+       glutStrokeWidth
+       glutBitmapLength
+       glutStrokeLength
+       glutBitmapHeight
+       glutStrokeHeight
+       glutBitmapString
+       glutStrokeString
+       glutWireCube
+       glutSolidCube
+       glutWireSphere
+       glutSolidSphere
+       glutWireCone
+       glutSolidCone
+       glutWireTorus
+       glutSolidTorus
+       glutWireDodecahedron
+       glutSolidDodecahedron
+       glutWireOctahedron
+       glutSolidOctahedron
+       glutWireTetrahedron
+       glutSolidTetrahedron
+       glutWireIcosahedron
+       glutSolidIcosahedron
+       glutWireRhombicDodecahedron
+       glutSolidRhombicDodecahedron
+       glutWireSierpinskiSponge
+       glutSolidSierpinskiSponge
+       glutWireTeapot
+       glutSolidTeapot
+       glutGameModeString
+       glutEnterGameMode
+       glutLeaveGameMode
+       glutGameModeGet
+       glutVideoResizeGet
+       glutSetupVideoResizing
+       glutStopVideoResizing
+       glutVideoResize
+       glutVideoPan
+       glutSetColor
+       glutGetColor
+       glutCopyColormap
+       glutIgnoreKeyRepeat
+       glutSetKeyRepeat
+       glutForceJoystickFunc
+       glutExtensionSupported
+       glutReportErrors
+
diff --git a/src/templates/cpp_template b/src/templates/cpp_template
new file mode 100644 (file)
index 0000000..9d4d4fa
--- /dev/null
@@ -0,0 +1,17 @@
+INVALID TEMPLATE, MOVED TO XFREE86-STYLE LICENSE
+
+/*
+ * |FILENAME|
+ *
+ * Here comes the file's contents description.
+ *
+ * Copyright (c) |YEAR| by |AUTHOR|
+ * Written by |AUTHOR|, <|EMAIL|>
+ * Creation date: |DATE|
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
diff --git a/src/templates/header_template b/src/templates/header_template
new file mode 100644 (file)
index 0000000..9d4d4fa
--- /dev/null
@@ -0,0 +1,17 @@
+INVALID TEMPLATE, MOVED TO XFREE86-STYLE LICENSE
+
+/*
+ * |FILENAME|
+ *
+ * Here comes the file's contents description.
+ *
+ * Copyright (c) |YEAR| by |AUTHOR|
+ * Written by |AUTHOR|, <|EMAIL|>
+ * Creation date: |DATE|
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
index cf66858..45467cd 100644 (file)
@@ -2,5 +2,5 @@
 
 bin_PROGRAMS = one
 one_SOURCES = one.c
-one_LDFLAGS = -export-dynamic -dlpreopen ../freeglut-1.3/libfreeglut-1.3.la
+one_LDFLAGS = -export-dynamic -dlpreopen ../src/libfreeglut-1.3.la