diff --git a/Graphics/Rendering/OGL.hs b/Graphics/Rendering/OGL.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL.hs
@@ -0,0 +1,131 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- A convenience module, combining the Haskell bindings for GL and GLU.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL (
+   -- * Supported Extensions
+
+   -- $SupportedExtensions
+
+   -- * Legal stuff
+
+   -- $LegalStuff
+
+     module Graphics.Rendering.OGL.GL
+   , module Graphics.Rendering.OGL.GLU
+   , module Graphics.Rendering.OGL.Monad
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL
+import Graphics.Rendering.OGL.GLU
+
+--------------------------------------------------------------------------------
+-- $SupportedExtensions
+-- There is support for full OpenGL 2.1, including the imaging subset, plus some
+-- extensions:
+--
+-- @
+-- extension                      | core since
+-- -------------------------------+------------
+-- GL_APPLE_packed_pixels         | 1.2
+-- GL_ARB_depth_texture           | 1.4
+-- GL_ARB_imaging                 |
+-- GL_ARB_multisample             | 1.3
+-- GL_ARB_multitexture            | 1.3
+-- GL_ARB_occlusion_query         | 1.5
+-- GL_ARB_point_parameters        | 1.4
+-- GL_ARB_point_sprite            |
+-- GL_ARB_shadow                  | 1.4
+-- GL_ARB_texture_border_clamp    | 1.3
+-- GL_ARB_texture_compression     | 1.3
+-- GL_ARB_texture_cube_map        | 1.3
+-- GL_ARB_texture_env_add         | 1.3
+-- GL_ARB_texture_env_combine     | 1.3
+-- GL_ARB_texture_env_crossbar    | 1.4
+-- GL_ARB_texture_env_dot3        | 1.3
+-- GL_ARB_texture_mirrored_repeat | 1.4
+-- GL_ARB_transpose_matrix        | 1.3
+-- GL_ARB_vertex_buffer_object    | 1.5
+-- GL_ARB_window_pos              | 1.4
+-- GL_EXT_abgr                    |
+-- GL_EXT_bgra                    | 1.2
+-- GL_EXT_blend_color             | 1.4
+-- GL_EXT_blend_func_separate     | 1.4
+-- GL_EXT_blend_logic_op          | 1.1
+-- GL_EXT_blend_minmax            | 1.4
+-- GL_EXT_blend_subtract          | 1.4
+-- GL_EXT_color_subtable          |
+-- GL_EXT_compiled_vertex_array   |
+-- GL_EXT_convolution             |
+-- GL_EXT_copy_texture            | 1.1
+-- GL_EXT_depth_bounds_test       |
+-- GL_EXT_draw_range_elements     | 1.2
+-- GL_EXT_fog_coord               | 1.4
+-- GL_EXT_histogram               |
+-- GL_EXT_multi_draw_arrays       | 1.4
+-- GL_EXT_packed_pixels           | 1.2
+-- GL_EXT_polygon_offset          | 1.1
+-- GL_EXT_rescale_normal          | 1.2
+-- GL_EXT_secondary_color         | 1.4
+-- GL_EXT_separate_specular_color | 1.2
+-- GL_EXT_shadow_funcs            | 1.5
+-- GL_EXT_stencil_two_side        |
+-- GL_EXT_stencil_wrap            | 1.4
+-- GL_EXT_subtexture              | 1.1
+-- GL_EXT_texture                 | 1.1
+-- GL_EXT_texture3D               | 1.2
+-- GL_EXT_texture_lod_bias        | 1.4
+-- GL_EXT_texture_object          | 1.1
+-- GL_EXT_vertex_array            | 1.1
+-- GL_HP_convolution_border_modes |
+-- GL_IBM_rasterpos_clip          |
+-- GL_NV_blend_square             | 1.4
+-- GL_NV_depth_clamp              |
+-- GL_NV_fog_distance             |
+-- GL_NV_light_max_exponent       |
+-- GL_NV_packed_depth_stencil     |
+-- GL_NV_primitive_restart        |
+-- GL_SGIS_generate_mipmap        | 1.4
+-- GL_SGIS_texture_edge_clamp     |
+-- GL_SGIS_texture_lod            |
+-- GL_SGI_color_matrix            |
+-- GL_SGI_color_table             |
+-- @
+
+--------------------------------------------------------------------------------
+-- $LegalStuff
+-- The documentation is loosely based on the man pages of the OpenGL Sample
+-- Implemenation from SGI, see: <http://oss.sgi.com/projects/ogl-sample/>. It is
+-- used under the SGI Free Software License B. This license requires the
+-- following notice:
+--
+-- /License Applicability/. Except to the extent portions of this file are made
+-- subject to an alternative license as permitted in the SGI Free Software
+-- License B, Version 1.1 (the \"License\"), the contents of this file are
+-- subject only to the provisions of the License. You may not use this file
+-- except in compliance with the License. You may obtain a copy of the License
+-- at Silicon Graphics, Inc., attn: Legal Services, 1600 Amphitheatre Parkway,
+-- Mountain View, CA 94043-1351, or at: <http://oss.sgi.com/projects/FreeB/>.
+-- 
+-- Note that, as provided in the License, the Software is distributed on an \"AS
+-- IS\" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+-- DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+-- CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR
+-- PURPOSE, AND NON-INFRINGEMENT.
+--
+-- /Original Code/. The Original Code is: OpenGL Sample Implementation, Version
+-- 1.2.1, released January 26, 2000, developed by Silicon Graphics, Inc. The
+-- Original Code is Copyright (c) 1991-2002 Silicon Graphics, Inc.  Copyright in
+-- any portions created by third parties is as indicated elsewhere herein. All
+-- Rights Reserved.
diff --git a/Graphics/Rendering/OGL/GL.hs b/Graphics/Rendering/OGL/GL.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL.hs
@@ -0,0 +1,95 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- A Haskell binding for OpenGL, the industry\'s most widely used and
+-- supported 2D and 3D graphics API.
+--
+-----------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL (
+   -- * OpenGL Operation
+   module Graphics.Rendering.OGL.GL.BasicTypes,
+   module Graphics.Rendering.OGL.GL.BeginEnd,
+   module Graphics.Rendering.OGL.GL.VertexSpec,
+   module Graphics.Rendering.OGL.GL.VertexArrays,
+   module Graphics.Rendering.OGL.GL.BufferObjects,
+   module Graphics.Rendering.OGL.GL.Rectangles,
+   module Graphics.Rendering.OGL.GL.CoordTrans,
+   module Graphics.Rendering.OGL.GL.Clipping,
+   module Graphics.Rendering.OGL.GL.RasterPos,
+   module Graphics.Rendering.OGL.GL.Colors,
+   module Graphics.Rendering.OGL.GL.Shaders,
+
+   -- * Rasterization
+   module Graphics.Rendering.OGL.GL.Antialiasing,
+   module Graphics.Rendering.OGL.GL.Points,
+   module Graphics.Rendering.OGL.GL.LineSegments,
+   module Graphics.Rendering.OGL.GL.Polygons,
+   module Graphics.Rendering.OGL.GL.PixelRectangles,
+   module Graphics.Rendering.OGL.GL.Bitmaps,
+   module Graphics.Rendering.OGL.GL.Texturing,
+   module Graphics.Rendering.OGL.GL.ColorSum,
+   module Graphics.Rendering.OGL.GL.Fog,
+
+   -- * Per-Fragment Operations and the Framebuffer
+   module Graphics.Rendering.OGL.GL.PerFragment,
+   module Graphics.Rendering.OGL.GL.Framebuffer,
+   module Graphics.Rendering.OGL.GL.ReadCopyPixels,
+
+   -- * Special Functions
+   module Graphics.Rendering.OGL.GL.Evaluators,
+   module Graphics.Rendering.OGL.GL.Selection,
+   module Graphics.Rendering.OGL.GL.Feedback,
+   module Graphics.Rendering.OGL.GL.DisplayLists,
+   module Graphics.Rendering.OGL.GL.FlushFinish,
+   module Graphics.Rendering.OGL.GL.Hints,
+
+   -- * State and State Requests
+   module Graphics.Rendering.OGL.GL.StateVar,
+   module Graphics.Rendering.OGL.GL.StringQueries,
+   module Graphics.Rendering.OGL.GL.SavingState
+) where
+
+import Graphics.Rendering.OGL.GL.BasicTypes
+import Graphics.Rendering.OGL.GL.BeginEnd
+import Graphics.Rendering.OGL.GL.VertexSpec
+import Graphics.Rendering.OGL.GL.VertexArrays
+import Graphics.Rendering.OGL.GL.BufferObjects
+import Graphics.Rendering.OGL.GL.Rectangles
+import Graphics.Rendering.OGL.GL.CoordTrans
+import Graphics.Rendering.OGL.GL.Clipping
+import Graphics.Rendering.OGL.GL.RasterPos
+import Graphics.Rendering.OGL.GL.Colors
+import Graphics.Rendering.OGL.GL.Shaders
+
+import Graphics.Rendering.OGL.GL.Antialiasing
+import Graphics.Rendering.OGL.GL.Points
+import Graphics.Rendering.OGL.GL.LineSegments
+import Graphics.Rendering.OGL.GL.Polygons
+import Graphics.Rendering.OGL.GL.PixelRectangles
+import Graphics.Rendering.OGL.GL.Bitmaps
+import Graphics.Rendering.OGL.GL.Texturing
+import Graphics.Rendering.OGL.GL.ColorSum
+import Graphics.Rendering.OGL.GL.Fog
+
+import Graphics.Rendering.OGL.GL.PerFragment
+import Graphics.Rendering.OGL.GL.Framebuffer
+import Graphics.Rendering.OGL.GL.ReadCopyPixels
+
+import Graphics.Rendering.OGL.GL.Evaluators
+import Graphics.Rendering.OGL.GL.Selection
+import Graphics.Rendering.OGL.GL.Feedback
+import Graphics.Rendering.OGL.GL.DisplayLists
+import Graphics.Rendering.OGL.GL.FlushFinish
+import Graphics.Rendering.OGL.GL.Hints
+
+import Graphics.Rendering.OGL.GL.StateVar
+import Graphics.Rendering.OGL.GL.StringQueries
+import Graphics.Rendering.OGL.GL.SavingState
diff --git a/Graphics/Rendering/OGL/GL/Antialiasing.hs b/Graphics/Rendering/OGL/GL/Antialiasing.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Antialiasing.hs
@@ -0,0 +1,43 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Antialiasing
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.2 (Antialiasing) of the OpenGL 2.1
+-- specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Antialiasing (
+   sampleBuffers, samples, multisample, subpixelBits
+) where
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapMultisample), makeCapability )
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLsizei, Capability )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetSampleBuffers,GetSamples,GetSubpixelBits), getSizei1 )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar, StateVar )
+
+--------------------------------------------------------------------------------
+
+sampleBuffers :: GettableStateVar GLsizei
+sampleBuffers = antialiasingInfo GetSampleBuffers
+
+samples :: GettableStateVar GLsizei
+samples = antialiasingInfo GetSamples
+
+multisample :: StateVar Capability
+multisample = makeCapability CapMultisample
+
+subpixelBits :: GettableStateVar GLsizei
+subpixelBits = antialiasingInfo GetSubpixelBits
+
+antialiasingInfo :: GetPName -> GettableStateVar GLsizei
+antialiasingInfo = makeGettableStateVar . getSizei1 id
diff --git a/Graphics/Rendering/OGL/GL/BasicTypes.hs b/Graphics/Rendering/OGL/GL/BasicTypes.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/BasicTypes.hs
@@ -0,0 +1,110 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.BasicTypes
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 2.3 (GL Command Sytax) of the OpenGL 2.1
+-- specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.BasicTypes (
+   GLboolean, GLbyte, GLubyte, GLchar, GLshort, GLushort, GLint, GLuint,
+   GLsizei, GLenum, GLintptr, GLsizeiptr, GLbitfield, GLfloat, GLclampf,
+   GLdouble, GLclampd, Capability(..)
+) where
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLConfig.h"
+
+--------------------------------------------------------------------------------
+
+import Data.Int
+import Data.Word
+
+-- If we don't find modern OpenGL headers at configuration time, make some
+-- educated guesses here.
+
+#if !defined(HTYPE_GLCHAR) || !defined(HTYPE_GLINTPTR) || !defined(HTYPE_GLSIZEIPTR)
+import Foreign.C.Types
+#endif
+
+#if !defined(HTYPE_GLCHAR)
+#define HTYPE_GLCHAR CChar
+#endif
+
+#if !defined(HTYPE_GLINTPTR)
+#define HTYPE_GLINTPTR CPtrdiff
+#endif
+
+#if !defined(HTYPE_GLSIZEIPTR)
+#define HTYPE_GLSIZEIPTR CPtrdiff
+#endif
+
+--------------------------------------------------------------------------------
+
+-- | Boolean (min. 1 bit)
+type GLboolean = HTYPE_GLBOOLEAN
+
+-- | Signed 2\'s complement binary integer (min. 8 bits)
+type GLbyte = HTYPE_GLBYTE
+
+-- | Unsigned binary integer (min. 8 bits)
+type GLubyte = HTYPE_GLUBYTE
+
+-- | Characters making up strings
+type GLchar = HTYPE_GLCHAR
+
+-- | Signed 2\'s complement binary integer (min. 16 bits)
+type GLshort = HTYPE_GLSHORT
+
+-- | Unsigned binary integer (min. 16 bits)
+type GLushort = HTYPE_GLUSHORT
+
+-- | Signed 2\'s complement binary integer (min. 32 bits)
+type GLint = HTYPE_GLINT
+
+-- | Unsigned binary integer (min. 32 bits)
+type GLuint = HTYPE_GLUINT
+
+-- | Non-negatitve binary integer size (min. 32 bits)
+type GLsizei = HTYPE_GLSIZEI
+
+-- | Enumerated binary integer value (min. 32 bits)
+type GLenum = HTYPE_GLENUM
+
+-- | Signed 2\'s complement binary integer (sufficiently large enough to hold
+-- any address)
+type GLintptr = HTYPE_GLINTPTR
+
+-- | Non-negatitve binary integer size (sufficiently large enough to hold any
+-- address)
+type GLsizeiptr = HTYPE_GLSIZEIPTR
+
+-- | Bit field (min. 32 bits)
+type GLbitfield = HTYPE_GLBITFIELD
+
+-- | Floating-point value (min. 32 bits)
+type GLfloat = HTYPE_GLFLOAT
+
+-- | Floating-point value clamped to [0,1] (min. 32 bits)
+type GLclampf = HTYPE_GLCLAMPF
+
+-- | Floating-point value (min. 64 bits)
+type GLdouble = HTYPE_GLDOUBLE
+
+-- | Floating-point value clamped to [0,1] (min. 64 bits)
+type GLclampd = HTYPE_GLCLAMPD
+
+--------------------------------------------------------------------------------
+
+data Capability =
+     Disabled
+   | Enabled
+   deriving ( Eq, Ord, Show )
diff --git a/Graphics/Rendering/OGL/GL/BeginEnd.hs b/Graphics/Rendering/OGL/GL/BeginEnd.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/BeginEnd.hs
@@ -0,0 +1,147 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.BeginEnd
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 2.6 (Begin\/End Paradigm) of the
+-- OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.BeginEnd (
+   -- * Begin and End Objects
+   PrimitiveMode(..),
+   renderPrimitive, unsafeRenderPrimitive, primitiveRestart,
+
+   -- * Polygon Edges
+   EdgeFlag(..),
+   edgeFlag
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum, GLboolean )
+import Graphics.Rendering.OGL.GL.EdgeFlag (
+   EdgeFlag(..), marshalEdgeFlag, unmarshalEdgeFlag )
+import Graphics.Rendering.OGL.GL.Exception ( bracket_, unsafeBracket_ )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.PrimitiveMode (
+   PrimitiveMode(..), marshalPrimitiveMode )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   getBoolean1, GetPName(GetEdgeFlag) )
+import Graphics.Rendering.OGL.GL.StateVar ( StateVar, makeStateVar )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+
+--------------------------------------------------------------------------------
+
+-- | Delimit the vertices that define a primitive or a group of like primitives.
+--
+-- Only a subset of GL commands can be used in the delimited action:
+-- Those for specifying vertex coordinates
+-- ('Graphics.Rendering.OGL.GL.VertexSpec.vertex',
+--  'Graphics.Rendering.OGL.GL.VertexSpec.vertexv'),
+-- vertex colors
+-- ('Graphics.Rendering.OGL.GL.VertexSpec.color',
+--  'Graphics.Rendering.OGL.GL.VertexSpec.colorv',
+--  'Graphics.Rendering.OGL.GL.VertexSpec.secondaryColor',
+--  'Graphics.Rendering.OGL.GL.VertexSpec.secondaryColorv',
+--  'Graphics.Rendering.OGL.GL.VertexSpec.index', 
+--  'Graphics.Rendering.OGL.GL.VertexSpec.indexv'),
+-- normal
+-- ('Graphics.Rendering.OGL.GL.VertexSpec.normal', 
+--  'Graphics.Rendering.OGL.GL.VertexSpec.normalv'),
+-- texture coordinates
+-- ('Graphics.Rendering.OGL.GL.VertexSpec.texCoord', 
+--  'Graphics.Rendering.OGL.GL.VertexSpec.texCoordv',
+--  'Graphics.Rendering.OGL.GL.VertexSpec.multiTexCoord',
+--  'Graphics.Rendering.OGL.GL.VertexSpec.multiTexCoordv'),
+-- and fog coordinates
+-- ('Graphics.Rendering.OGL.GL.VertexSpec.fogCoord', 
+--  'Graphics.Rendering.OGL.GL.VertexSpec.fogCoordv').
+-- Additionally,
+-- 'Graphics.Rendering.OGL.GL.Evaluators.evalPoint1', 
+-- 'Graphics.Rendering.OGL.GL.Evaluators.evalPoint2',
+-- 'Graphics.Rendering.OGL.GL.Evaluators.evalCoord1', 
+-- 'Graphics.Rendering.OGL.GL.Evaluators.evalCoord1v',
+-- 'Graphics.Rendering.OGL.GL.Evaluators.evalCoord2',
+-- 'Graphics.Rendering.OGL.GL.Evaluators.evalCoord2v',
+-- 'Graphics.Rendering.OGL.GL.Colors.materialAmbient',
+-- 'Graphics.Rendering.OGL.GL.Colors.materialDiffuse',
+-- 'Graphics.Rendering.OGL.GL.Colors.materialAmbientAndDiffuse',
+-- 'Graphics.Rendering.OGL.GL.Colors.materialSpecular',
+-- 'Graphics.Rendering.OGL.GL.Colors.materialEmission',
+-- 'Graphics.Rendering.OGL.GL.Colors.materialShininess',
+-- 'Graphics.Rendering.OGL.GL.DisplayLists.callList',
+-- 'Graphics.Rendering.OGL.GL.DisplayLists.callLists',
+-- and setting 'edgeFlag' are allowed. Writing the respective state variables
+-- is allowed in the delimited action, too.
+--
+-- Regardless of the chosen 'PrimitiveMode', there is no limit to the number of
+-- vertices that can be defined during a single 'renderPrimitive'. Lines,
+-- triangles, quadrilaterals, and polygons that are incompletely specified are
+-- not drawn. Incomplete specification results when either too few vertices are
+-- provided to specify even a single primitive or when an incorrect multiple of
+-- vertices is specified. The incomplete primitive is ignored; the rest are
+-- drawn.
+--
+-- The minimum specification of vertices for each primitive is as follows: 1
+-- for a point, 2 for a line, 3 for a triangle, 4 for a quadrilateral, and 3 for
+-- a polygon. Modes that require a certain multiple of vertices are 'Lines' (2),
+-- 'Triangles' (3), 'Quads' (4), and 'QuadStrip' (2).
+
+renderPrimitive :: PrimitiveMode -> PrimitiveGL a -> GL a
+renderPrimitive x y = liftIO $ renderPrim bracket_ x (runPrimitive y)
+
+-- | A more efficient, but potentially dangerous version of 'renderPrimitive':
+-- The given action is not allowed to throw an exception.
+
+unsafeRenderPrimitive :: PrimitiveMode -> PrimitiveGL a -> GL a
+unsafeRenderPrimitive x y = liftIO $ renderPrim unsafeBracket_ x (runPrimitive y)
+
+{-# INLINE renderPrim #-}
+renderPrim :: (IO () -> IO () -> IO a -> IO a) -> PrimitiveMode -> IO a -> IO a
+renderPrim brack_ beginMode =
+   brack_ (glBegin (marshalPrimitiveMode beginMode)) glEnd
+
+foreign import CALLCONV unsafe "glBegin" glBegin :: GLenum -> IO ()
+
+foreign import CALLCONV unsafe "glEnd" glEnd :: IO ()
+
+--------------------------------------------------------------------------------
+
+primitiveRestart :: GL ()
+primitiveRestart = liftIO $ glPrimitiveRestartNV
+
+EXTENSION_ENTRY("GL_NV_primitive_restart",glPrimitiveRestartNV,IO ())
+
+--------------------------------------------------------------------------------
+
+-- | Each vertex of a polygon, separate triangle, or separate quadrilateral
+-- specified during 'renderPrimitive' is marked as the start of either a boundary
+-- or nonboundary (interior) edge.
+--
+-- The vertices of connected triangles and connected quadrilaterals are always
+-- marked as boundary, regardless of the value of the edge flag.
+--
+-- Boundary and nonboundary edge flags on vertices are significant only if
+-- 'Graphics.Rendering.OGL.GL.Polygons.polygonMode' is set to
+-- 'Graphics.Rendering.OGL.GL.Polygons.Point' or
+-- 'Graphics.Rendering.OGL.GL.Polygons.Line'.
+--
+-- Note that the current edge flag can be updated at any time, in particular
+-- during 'renderPrimitive'.
+
+edgeFlag :: StateVar EdgeFlag
+edgeFlag =
+   makeStateVar (getBoolean1 unmarshalEdgeFlag GetEdgeFlag)
+                (glEdgeFlag . marshalEdgeFlag)
+
+foreign import CALLCONV unsafe "glEdgeFlag" glEdgeFlag :: GLboolean -> IO ()
diff --git a/Graphics/Rendering/OGL/GL/Bitmaps.hs b/Graphics/Rendering/OGL/GL/Bitmaps.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Bitmaps.hs
@@ -0,0 +1,33 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Bitmaps
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.7 (Bitmaps) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Bitmaps (
+   bitmap
+) where
+
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLsizei, GLfloat )
+import Graphics.Rendering.OGL.GL.CoordTrans ( Size(..), Vector2(..) )
+import Graphics.Rendering.OGL.GL.VertexSpec ( Vertex2(..) )
+
+--------------------------------------------------------------------------------
+
+bitmap :: Size -> (Vertex2 GLfloat) -> (Vector2 GLfloat) -> Ptr a -> GL ()
+bitmap (Size w h) (Vertex2 xbo ybo) (Vector2 xbi ybi) = 
+   glBitmap w h xbo ybo xbi ybi
+
+foreign import CALLCONV unsafe "glBitmap"
+   glBitmap :: GLsizei -> GLsizei -> GLfloat -> GLfloat -> GLfloat -> GLfloat
+            -> Ptr a -> GL ()
diff --git a/Graphics/Rendering/OGL/GL/BlendingFactor.hs b/Graphics/Rendering/OGL/GL/BlendingFactor.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/BlendingFactor.hs
@@ -0,0 +1,78 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.BlendingFactor
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for (un-)marshaling BlendingFactor.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.BlendingFactor (
+   BlendingFactor(..), marshalBlendingFactor, unmarshalBlendingFactor
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum )
+
+--------------------------------------------------------------------------------
+
+data BlendingFactor =
+     Zero
+   | One
+   | SrcColor
+   | OneMinusSrcColor
+   | DstColor
+   | OneMinusDstColor
+   | SrcAlpha
+   | OneMinusSrcAlpha
+   | DstAlpha
+   | OneMinusDstAlpha
+   | ConstantColor
+   | OneMinusConstantColor
+   | ConstantAlpha
+   | OneMinusConstantAlpha
+   | SrcAlphaSaturate
+   deriving ( Eq, Ord, Show )
+
+marshalBlendingFactor :: BlendingFactor -> GLenum
+marshalBlendingFactor x = case x of
+   Zero -> 0x0
+   One -> 0x1
+   SrcColor -> 0x300
+   OneMinusSrcColor -> 0x301
+   DstColor -> 0x306
+   OneMinusDstColor -> 0x307
+   SrcAlpha -> 0x302
+   OneMinusSrcAlpha -> 0x303
+   DstAlpha -> 0x304
+   OneMinusDstAlpha -> 0x305
+   ConstantColor -> 0x8001
+   OneMinusConstantColor -> 0x8002
+   ConstantAlpha -> 0x8003
+   OneMinusConstantAlpha -> 0x8004
+   SrcAlphaSaturate -> 0x308
+
+unmarshalBlendingFactor :: GLenum -> BlendingFactor
+unmarshalBlendingFactor x
+   | x == 0x0 = Zero
+   | x == 0x1 = One
+   | x == 0x300 = SrcColor
+   | x == 0x301 = OneMinusSrcColor
+   | x == 0x306 = DstColor
+   | x == 0x307 = OneMinusDstColor
+   | x == 0x302 = SrcAlpha
+   | x == 0x303 = OneMinusSrcAlpha
+   | x == 0x304 = DstAlpha
+   | x == 0x305 = OneMinusDstAlpha
+   | x == 0x8001 = ConstantColor
+   | x == 0x8002 = OneMinusConstantColor
+   | x == 0x8003 = ConstantAlpha
+   | x == 0x8004 = OneMinusConstantAlpha
+   | x == 0x308 = SrcAlphaSaturate
+   | otherwise = error ("unmarshalBlendingFactor: illegal value " ++ show x)
diff --git a/Graphics/Rendering/OGL/GL/BufferMode.hs b/Graphics/Rendering/OGL/GL/BufferMode.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/BufferMode.hs
@@ -0,0 +1,94 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.BufferMode
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for (un-)marshaling BufferMode.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.BufferMode (
+   BufferMode(..), marshalBufferMode, unmarshalBufferMode
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum, GLsizei )
+
+--------------------------------------------------------------------------------
+
+-- | The set of color buffers which are selected for reading and writing.
+
+data BufferMode =
+     NoBuffers
+     -- ^ No color buffers are selected.
+   | FrontLeftBuffer
+     -- ^ Only the front left color buffer is selected.
+   | FrontRightBuffer
+     -- ^ Only the front right color buffer is selected.
+   | BackLeftBuffer
+     -- ^ Only the  back left color buffer is selected.
+   | BackRightBuffer
+     -- ^ Only the back right color buffer is selected.
+   | FrontBuffers
+     -- ^ Only the front left and front right color buffers are selected. If
+     -- there is no front right color buffer, only the front left color buffer
+     -- is selected.
+   | BackBuffers
+     -- ^ Only the back left and back right color buffers are selected. If there
+     -- is no back right color buffer, only the back left color buffer is
+     -- selected.
+   | LeftBuffers
+     -- ^ Only the front left and back left color buffers are selected. If there
+     -- is no back left color buffer, only the front left color buffer is
+     -- selected.
+   | RightBuffers
+     -- ^ Only the front right and back right color buffers are selected. If
+     -- there is no back right color buffer, only the front right color buffer
+     -- is selected.
+   | FrontAndBackBuffers
+     -- ^ All the front and back color buffers (front left, front right, back
+     -- left, back right) are selected. If there are no back color buffers, only
+     -- the front left and front right color buffers are selected. If there are
+     -- no right color buffers, only the front left and back left color buffers
+     -- are selected. If there are no right or back color buffers, only the
+     -- front left color buffer is selected.
+   | AuxBuffer GLsizei
+     -- ^ Only the given auxiliary color buffer no. /i/ is selected.
+   deriving ( Eq, Ord, Show )
+
+marshalBufferMode :: BufferMode -> Maybe GLenum
+marshalBufferMode x = case x of
+   NoBuffers -> Just 0x0
+   FrontLeftBuffer -> Just 0x400
+   FrontRightBuffer -> Just 0x401
+   BackLeftBuffer -> Just 0x402
+   BackRightBuffer -> Just 0x403
+   FrontBuffers -> Just 0x404
+   BackBuffers -> Just 0x405
+   LeftBuffers -> Just 0x406
+   RightBuffers -> Just 0x407
+   FrontAndBackBuffers -> Just 0x408
+   AuxBuffer i
+      | i <= 246  -> Just (0x409 + fromIntegral i)
+      | otherwise -> Nothing
+
+unmarshalBufferMode :: GLenum -> BufferMode
+unmarshalBufferMode x
+   | x == 0x0 = NoBuffers
+   | x == 0x400 = FrontLeftBuffer
+   | x == 0x401 = FrontRightBuffer
+   | x == 0x402 = BackLeftBuffer
+   | x == 0x403 = BackRightBuffer
+   | x == 0x404 = FrontBuffers
+   | x == 0x405 = BackBuffers
+   | x == 0x406 = LeftBuffers
+   | x == 0x407 = RightBuffers
+   | x == 0x408 = FrontAndBackBuffers
+   | 0x409 <= x && x <= 0x4ff = AuxBuffer (fromIntegral x - 0x409)
+   | otherwise = error ("unmarshalBufferMode: illegal value " ++ show x)
diff --git a/Graphics/Rendering/OGL/GL/BufferObjects.hs b/Graphics/Rendering/OGL/GL/BufferObjects.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/BufferObjects.hs
@@ -0,0 +1,324 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.BufferObjects
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 2.9 (Buffer Objects) of the OpenGL 2.1
+-- specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.BufferObjects (
+   -- * Object Names
+   ObjectName(..),
+
+   -- * Buffer Objects
+   BufferObject(BufferObject),
+
+   -- * Binding Buffer Objects
+   BufferTarget(..), bindBuffer, arrayBufferBinding,
+
+   -- * Handling Buffer Data
+   BufferUsage(..), bufferData, TransferDirection(..), bufferSubData,
+
+   -- * Mapping Buffer Objects
+   BufferAccess(..), MappingFailure(..), withMappedBuffer,
+   bufferAccess, bufferMapped, mapBuffer, unmapBuffer
+) where
+
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Marshal.Array ( withArrayLen, peekArray, allocaArray )
+import Foreign.Ptr ( Ptr, nullPtr )
+import Foreign.Storable ( Storable(peek) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLboolean, GLenum, GLint, GLintptr, GLuint, GLsizei, GLsizeiptr )
+import Graphics.Rendering.OGL.GL.Exception ( finallyRet )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.GLboolean ( unmarshalGLboolean )
+import Graphics.Rendering.OGL.GL.PeekPoke ( peek1 )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetArrayBufferBinding,GetElementArrayBufferBinding,
+            GetVertexArrayBufferBinding,GetNormalArrayBufferBinding,
+            GetColorArrayBufferBinding,GetIndexArrayBufferBinding,
+            GetTextureCoordArrayBufferBinding,GetEdgeFlagArrayBufferBinding,
+            GetFogCoordArrayBufferBinding,GetSecondaryColorArrayBufferBinding,
+            GetPixelPackBufferBinding,GetPixelUnpackBufferBinding ),
+   getInteger1 )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.VertexArrays ( ClientArrayType(..) )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal ( recordInvalidEnum )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+
+--------------------------------------------------------------------------------
+
+-- | An 'ObjectName' corresponds to the general OpenGL notion of an explicitly
+-- handled object name, e.g. a display list name, a texture object name, a
+-- buffer object name, etc.
+
+class ObjectName a where
+   genObjectNames :: Int -> GL [a]
+   deleteObjectNames:: [a] -> GL ()
+   isObjectName :: a -> GL Bool
+
+--------------------------------------------------------------------------------
+
+newtype BufferObject = BufferObject { bufferID :: GLuint }
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+instance ObjectName BufferObject where
+   genObjectNames n = liftIO . 
+      allocaArray n $ \buf -> do
+        glGenBuffersARB (fromIntegral n) buf
+        fmap (map BufferObject) $ peekArray n buf
+
+   deleteObjectNames bufferObjects = liftIO .
+      withArrayLen (map bufferID bufferObjects) $
+         glDeleteBuffersARB . fromIntegral
+
+   isObjectName = liftIO . fmap unmarshalGLboolean . glIsBufferARB . bufferID
+
+EXTENSION_ENTRY("GL_ARB_vertex_buffer_object or OpenGL 1.5",glGenBuffersARB,GLsizei -> Ptr GLuint -> IO ())
+
+EXTENSION_ENTRY("GL_ARB_vertex_buffer_object or OpenGL 1.5",glDeleteBuffersARB,GLsizei -> Ptr GLuint -> IO ())
+
+EXTENSION_ENTRY("GL_ARB_vertex_buffer_object or OpenGL 1.5",glIsBufferARB,GLuint -> IO GLboolean)
+
+--------------------------------------------------------------------------------
+
+data BufferTarget =
+     ArrayBuffer
+   | ElementArrayBuffer
+   | PixelPackBuffer
+   | PixelUnpackBuffer
+   deriving ( Eq, Ord, Show )
+
+marshalBufferTarget :: BufferTarget -> GLenum
+marshalBufferTarget x = case x of
+   ArrayBuffer -> 0x8892
+   ElementArrayBuffer -> 0x8893
+   PixelPackBuffer -> 0x88eb
+   PixelUnpackBuffer -> 0x88ec
+
+bufferTargetToGetPName :: BufferTarget -> GetPName
+bufferTargetToGetPName x = case x of
+   ArrayBuffer -> GetArrayBufferBinding
+   ElementArrayBuffer -> GetElementArrayBufferBinding
+   PixelPackBuffer -> GetPixelPackBufferBinding
+   PixelUnpackBuffer -> GetPixelUnpackBufferBinding
+
+--------------------------------------------------------------------------------
+
+data BufferUsage =
+     StreamDraw
+   | StreamRead
+   | StreamCopy
+   | StaticDraw
+   | StaticRead
+   | StaticCopy
+   | DynamicDraw
+   | DynamicRead
+   | DynamicCopy
+   deriving ( Eq, Ord, Show )
+
+marshalBufferUsage :: BufferUsage -> GLenum
+marshalBufferUsage x = case x of
+   StreamDraw -> 0x88e0
+   StreamRead -> 0x88e1
+   StreamCopy -> 0x88e2
+   StaticDraw -> 0x88e4
+   StaticRead -> 0x88e5
+   StaticCopy -> 0x88e6
+   DynamicDraw -> 0x88e8
+   DynamicRead -> 0x88e9
+   DynamicCopy -> 0x88ea
+
+unmarshalBufferUsage :: GLenum -> BufferUsage
+unmarshalBufferUsage x
+   | x == 0x88e0 = StreamDraw
+   | x == 0x88e1 = StreamRead
+   | x == 0x88e2 = StreamCopy
+   | x == 0x88e4 = StaticDraw
+   | x == 0x88e5 = StaticRead
+   | x == 0x88e6 = StaticCopy
+   | x == 0x88e8 = DynamicDraw
+   | x == 0x88e9 = DynamicRead
+   | x == 0x88ea = DynamicCopy
+   | otherwise = error ("unmarshalBufferUsage: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+data BufferAccess =
+     ReadOnly
+   | WriteOnly
+   | ReadWrite
+   deriving ( Eq, Ord, Show )
+
+marshalBufferAccess :: BufferAccess -> GLenum
+marshalBufferAccess x = case x of
+   ReadOnly -> 0x88b8
+   WriteOnly -> 0x88b9
+   ReadWrite -> 0x88ba
+
+unmarshalBufferAccess :: GLenum -> BufferAccess
+unmarshalBufferAccess x
+   | x == 0x88b8 = ReadOnly
+   | x == 0x88b9 = WriteOnly
+   | x == 0x88ba = ReadWrite
+   | otherwise = error ("unmarshalBufferAccess: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+bindBuffer :: BufferTarget -> StateVar (Maybe BufferObject)
+bindBuffer t = makeStateVar (getBindBuffer t) (setBindBuffer t)
+
+getBindBuffer :: BufferTarget -> IO (Maybe BufferObject)
+getBindBuffer = bufferQuery bufferTargetToGetPName
+
+bufferQuery :: (a -> GetPName) -> a -> IO (Maybe BufferObject)
+bufferQuery func t = do
+   buf <- getInteger1 (BufferObject . fromIntegral) (func t)
+   return $ if buf == noBufferObject then Nothing else Just buf
+
+noBufferObject :: BufferObject
+noBufferObject = BufferObject 0
+
+setBindBuffer :: BufferTarget -> Maybe BufferObject -> IO ()
+setBindBuffer t =
+   glBindBufferARB (marshalBufferTarget t) . bufferID . maybe noBufferObject id
+
+EXTENSION_ENTRY("GL_ARB_vertex_buffer_object or OpenGL 1.5",glBindBufferARB,GLenum -> GLuint -> IO ())
+
+clientArrayTypeToGetPName :: ClientArrayType -> GetPName
+clientArrayTypeToGetPName x = case x of
+   VertexArray -> GetVertexArrayBufferBinding
+   NormalArray -> GetNormalArrayBufferBinding
+   ColorArray -> GetColorArrayBufferBinding
+   IndexArray -> GetIndexArrayBufferBinding
+   TextureCoordArray -> GetTextureCoordArrayBufferBinding
+   EdgeFlagArray -> GetEdgeFlagArrayBufferBinding
+   FogCoordArray -> GetFogCoordArrayBufferBinding
+   SecondaryColorArray -> GetSecondaryColorArrayBufferBinding
+   MatrixIndexArray -> error "clientArrayTypeToGetPName: impossible"
+
+arrayBufferBinding :: ClientArrayType -> GettableStateVar (Maybe BufferObject)
+arrayBufferBinding t =
+   makeGettableStateVar $ case t of
+      MatrixIndexArray -> do recordInvalidEnum ; return Nothing
+      _ -> bufferQuery clientArrayTypeToGetPName t
+
+--------------------------------------------------------------------------------
+
+bufferData :: BufferTarget -> StateVar (GLsizeiptr, Ptr a, BufferUsage)
+bufferData t = makeStateVar (getBufferData t) (setBufferData t)
+
+getBufferData :: BufferTarget -> IO (GLsizeiptr, Ptr a, BufferUsage)
+getBufferData t = do
+   s <- getBufferParameter t fromIntegral GetBufferSize
+   p <- getBufferPointer t
+   u <- getBufferParameter t unmarshalBufferUsage GetBufferUsage
+   return (s, p, u)
+
+setBufferData :: BufferTarget -> (GLsizeiptr, Ptr a, BufferUsage) -> IO ()
+setBufferData t (s, p, u) =
+   glBufferDataARB (marshalBufferTarget t) s p (marshalBufferUsage u)
+
+EXTENSION_ENTRY("GL_ARB_vertex_buffer_object or OpenGL 1.5",glBufferDataARB,GLenum -> GLsizeiptr -> Ptr a -> GLenum -> IO ())
+
+--------------------------------------------------------------------------------
+
+data TransferDirection =
+     ReadFromBuffer
+   | WriteToBuffer
+   deriving ( Eq, Ord, Show )
+
+bufferSubData ::
+   BufferTarget -> TransferDirection -> GLintptr -> GLsizeiptr -> Ptr a -> GL ()
+bufferSubData t WriteToBuffer = glBufferSubDataARB (marshalBufferTarget t)
+bufferSubData t ReadFromBuffer = glGetBufferSubDataARB (marshalBufferTarget t)
+
+EXTENSION_ENTRY("GL_ARB_vertex_buffer_object or OpenGL 1.5",glBufferSubDataARB,GLenum -> GLintptr -> GLsizeiptr -> Ptr a -> GL ())
+
+EXTENSION_ENTRY("GL_ARB_vertex_buffer_object or OpenGL 1.5",glGetBufferSubDataARB,GLenum -> GLintptr -> GLsizeiptr -> Ptr a -> GL ())
+
+--------------------------------------------------------------------------------
+
+data GetBufferPName =
+     GetBufferSize
+   | GetBufferUsage
+   | GetBufferAccess
+   | GetBufferMapped
+
+marshalGetBufferPName :: GetBufferPName -> GLenum
+marshalGetBufferPName x = case x of
+   GetBufferSize -> 0x8764
+   GetBufferUsage -> 0x8765
+   GetBufferAccess -> 0x88bb
+   GetBufferMapped -> 0x88bc
+
+getBufferParameter :: BufferTarget -> (GLenum -> a) -> GetBufferPName -> IO a
+getBufferParameter t f p = alloca $ \buf -> do
+   glGetBufferParameterivARB (marshalBufferTarget t)
+                             (marshalGetBufferPName p) buf
+   peek1 (f . fromIntegral) buf
+
+EXTENSION_ENTRY("GL_ARB_vertex_buffer_object or OpenGL 1.5",glGetBufferParameterivARB,GLenum -> GLenum -> Ptr GLint -> IO ())
+
+--------------------------------------------------------------------------------
+
+getBufferPointer :: BufferTarget -> IO (Ptr a)
+getBufferPointer t = alloca $ \buf -> do
+   -- only one pname: GL_BUFFER_MAP_POINTER
+   glGetBufferPointervARB (marshalBufferTarget t) 0x88bd buf
+   peek buf
+
+EXTENSION_ENTRY("GL_ARB_vertex_buffer_object or OpenGL 1.5",glGetBufferPointervARB,GLenum -> GLenum -> Ptr (Ptr a) -> IO ())
+
+--------------------------------------------------------------------------------
+
+data MappingFailure =
+     MappingFailed
+   | UnmappingFailed
+   deriving ( Eq, Ord, Show )
+
+withMappedBuffer :: BufferTarget -> BufferAccess -> (Ptr a -> GL b) -> (MappingFailure -> GL b) -> GL b
+withMappedBuffer t a action err = do
+   buf <- mapBuffer t a
+   if buf == nullPtr
+      then err MappingFailed
+      else do (ret, ok) <- liftIO $ finallyRet 
+									(runGL $ action buf) 
+									(runGL $ unmapBuffer t)
+              if ok
+                 then return ret
+                 else err UnmappingFailed
+
+mapBuffer :: BufferTarget -> BufferAccess -> GL (Ptr a)
+mapBuffer t = glMapBufferARB (marshalBufferTarget t) . marshalBufferAccess
+
+EXTENSION_ENTRY("GL_ARB_vertex_buffer_object or OpenGL 1.5",glMapBufferARB,GLenum -> GLenum -> GL (Ptr a))
+
+unmapBuffer :: BufferTarget -> GL Bool
+unmapBuffer = fmap unmarshalGLboolean . glUnmapBufferARB . marshalBufferTarget
+
+EXTENSION_ENTRY("GL_ARB_vertex_buffer_object or OpenGL 1.5",glUnmapBufferARB,GLenum -> GL GLboolean)
+
+bufferAccess :: BufferTarget -> GettableStateVar BufferAccess
+bufferAccess t = makeGettableStateVar $
+   getBufferParameter t unmarshalBufferAccess GetBufferAccess
+
+bufferMapped :: BufferTarget -> GettableStateVar Bool
+bufferMapped t = makeGettableStateVar $
+   getBufferParameter t unmarshalGLboolean GetBufferMapped
diff --git a/Graphics/Rendering/OGL/GL/Capability.hs b/Graphics/Rendering/OGL/GL/Capability.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Capability.hs
@@ -0,0 +1,270 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Capability
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for handling OpenGL capabilities, i.e.
+-- boolean state variables.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Capability (
+   marshalCapability, unmarshalCapability,
+   EnableCap(..), makeCapability, makeStateVarMaybe
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLboolean, GLenum, GLsizei, Capability(..) )
+import Graphics.Rendering.OGL.GL.GLboolean (
+   marshalGLboolean, unmarshalGLboolean )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   clipPlaneIndexToEnum, lightIndexToEnum )
+import Graphics.Rendering.OGL.GL.StateVar (
+   getIO, ($$=), StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal ( recordInvalidEnum )
+
+--------------------------------------------------------------------------------
+
+marshalCapability :: Capability -> GLboolean
+marshalCapability = marshalGLboolean . (Enabled ==)
+
+unmarshalCapability :: GLboolean -> Capability
+unmarshalCapability x = if unmarshalGLboolean x then Enabled else Disabled
+
+--------------------------------------------------------------------------------
+
+data EnableCap =
+     CapFog
+   | CapLighting
+   | CapTexture1D
+   | CapTexture2D
+   | CapLineStipple
+   | CapPolygonStipple
+   | CapCullFace
+   | CapAlphaTest
+   | CapBlend
+   | CapIndexLogicOp
+   | CapColorLogicOp
+   | CapDither
+   | CapStencilTest
+   | CapDepthTest
+   | CapClipPlane GLsizei
+   | CapLight GLsizei
+   | CapTextureGenS
+   | CapTextureGenT
+   | CapTextureGenR
+   | CapTextureGenQ
+   | CapMap1Vertex3
+   | CapMap1Vertex4
+   | CapMap1Color4
+   | CapMap1Index
+   | CapMap1Normal
+   | CapMap1TextureCoord1
+   | CapMap1TextureCoord2
+   | CapMap1TextureCoord3
+   | CapMap1TextureCoord4
+   | CapMap2Vertex3
+   | CapMap2Vertex4
+   | CapMap2Color4
+   | CapMap2Index
+   | CapMap2Normal
+   | CapMap2TextureCoord1
+   | CapMap2TextureCoord2
+   | CapMap2TextureCoord3
+   | CapMap2TextureCoord4
+   | CapPointSmooth
+   | CapLineSmooth
+   | CapPolygonSmooth
+   | CapScissorTest
+   | CapColorMaterial
+   | CapNormalize
+   | CapAutoNormal
+   | CapPolygonOffsetPoint
+   | CapPolygonOffsetLine
+   | CapPolygonOffsetFill
+   | CapVertexArray
+   | CapNormalArray
+   | CapColorArray
+   | CapIndexArray
+   | CapTextureCoordArray
+   | CapEdgeFlagArray
+   | CapFogCoordArray
+   | CapSecondaryColorArray
+   | CapMatrixIndexArray
+   | CapConvolution1D
+   | CapConvolution2D
+   | CapSeparable2D
+   | CapHistogram
+   | CapMinmax
+   | CapRescaleNormal
+   | CapSharedTexturePalette
+   | CapTexture3D
+   | CapMultisample
+   | CapSampleAlphaToCoverage
+   | CapSampleAlphaToOne
+   | CapSampleCoverage
+   | CapColorTable
+   | CapPostConvolutionColorTable
+   | CapPostColorMatrixColorTable
+   | CapColorSum
+   | CapTextureCubeMap
+   | CapWeightSumUnity
+   | CapVertexBlend
+   | CapWeightArray
+   | CapMatrixPalette
+   | CapDepthClamp
+   | CapDepthBoundsTest
+   | CapPrimitiveRestart -- NOTE: client state!
+   | CapPointSprite
+   | CapStencilTestTwoSide
+   | CapRasterPositionUnclipped
+   | CapTextureColorTable
+   | CapVertexProgramPointSize
+   | CapVertexProgramTwoSide
+
+marshalEnableCap :: EnableCap -> Maybe GLenum
+marshalEnableCap x = case x of
+   CapFog -> Just 0xb60
+   CapLighting -> Just 0xb50
+   CapTexture1D -> Just 0xde0
+   CapTexture2D -> Just 0xde1
+   CapLineStipple -> Just 0xb24
+   CapPolygonStipple -> Just 0xb42
+   CapCullFace -> Just 0xb44
+   CapAlphaTest -> Just 0xbc0
+   CapBlend -> Just 0xbe2
+   CapIndexLogicOp -> Just 0xbf1
+   CapColorLogicOp -> Just 0xbf2
+   CapDither -> Just 0xbd0
+   CapStencilTest -> Just 0xb90
+   CapDepthTest -> Just 0xb71
+   CapClipPlane i -> clipPlaneIndexToEnum i
+   CapLight i -> lightIndexToEnum i
+   CapTextureGenS -> Just 0xc60
+   CapTextureGenT -> Just 0xc61
+   CapTextureGenR -> Just 0xc62
+   CapTextureGenQ -> Just 0xc63
+   CapMap1Vertex3 -> Just 0xd97
+   CapMap1Vertex4 -> Just 0xd98
+   CapMap1Color4 -> Just 0xd90
+   CapMap1Index -> Just 0xd91
+   CapMap1Normal -> Just 0xd92
+   CapMap1TextureCoord1 -> Just 0xd93
+   CapMap1TextureCoord2 -> Just 0xd94
+   CapMap1TextureCoord3 -> Just 0xd95
+   CapMap1TextureCoord4 -> Just 0xd96
+   CapMap2Vertex3 -> Just 0xdb7
+   CapMap2Vertex4 -> Just 0xdb8
+   CapMap2Color4 -> Just 0xdb0
+   CapMap2Index -> Just 0xdb1
+   CapMap2Normal -> Just 0xdb2
+   CapMap2TextureCoord1 -> Just 0xdb3
+   CapMap2TextureCoord2 -> Just 0xdb4
+   CapMap2TextureCoord3 -> Just 0xdb5
+   CapMap2TextureCoord4 -> Just 0xdb6
+   CapPointSmooth -> Just 0xb10
+   CapLineSmooth -> Just 0xb20
+   CapPolygonSmooth -> Just 0xb41
+   CapScissorTest -> Just 0xc11
+   CapColorMaterial -> Just 0xb57
+   CapNormalize -> Just 0xba1
+   CapAutoNormal -> Just 0xd80
+   CapPolygonOffsetPoint -> Just 0x2a01
+   CapPolygonOffsetLine -> Just 0x2a02
+   CapPolygonOffsetFill -> Just 0x8037
+   CapVertexArray -> Just 0x8074
+   CapNormalArray -> Just 0x8075
+   CapColorArray -> Just 0x8076
+   CapIndexArray -> Just 0x8077
+   CapTextureCoordArray -> Just 0x8078
+   CapEdgeFlagArray -> Just 0x8079
+   CapFogCoordArray -> Just 0x8457
+   CapSecondaryColorArray -> Just 0x845e
+   CapMatrixIndexArray -> Just 0x8844
+   CapConvolution1D -> Just 0x8010
+   CapConvolution2D -> Just 0x8011
+   CapSeparable2D -> Just 0x8012
+   CapHistogram -> Just 0x8024
+   CapMinmax -> Just 0x802e
+   CapRescaleNormal -> Just 0x803a
+   CapSharedTexturePalette -> Just 0x81fb
+   CapTexture3D -> Just 0x806f
+   CapMultisample -> Just 0x809d
+   CapSampleAlphaToCoverage -> Just 0x809e
+   CapSampleAlphaToOne -> Just 0x809f
+   CapSampleCoverage -> Just 0x80a0
+   CapColorTable -> Just 0x80d0
+   CapPostConvolutionColorTable -> Just 0x80d1
+   CapPostColorMatrixColorTable -> Just 0x80d2
+   CapColorSum -> Just 0x8458
+   CapTextureCubeMap -> Just 0x8513
+   CapWeightSumUnity -> Just 0x86a6
+   CapVertexBlend -> Just 0x86a7
+   CapWeightArray -> Just 0x86ad
+   CapMatrixPalette -> Just 0x8840
+   CapDepthClamp -> Just 0x864f
+   CapDepthBoundsTest -> Just 0x8890
+   CapPrimitiveRestart -> Just 0x8558
+   CapPointSprite -> Just 0x8861
+   CapStencilTestTwoSide -> Just 0x8910
+   CapRasterPositionUnclipped -> Just 0x19262
+   CapTextureColorTable -> Just 0x80bc
+   CapVertexProgramPointSize -> Just 0x8642
+   CapVertexProgramTwoSide -> Just 0x8643
+
+--------------------------------------------------------------------------------
+
+makeCapability :: EnableCap -> StateVar Capability
+makeCapability cap = makeStateVar (isEnabled cap) (enable cap)
+
+--------------------------------------------------------------------------------
+
+isEnabled :: EnableCap -> IO Capability
+isEnabled =
+   maybe (do recordInvalidEnum; return Disabled)
+         (fmap unmarshalCapability . glIsEnabled) .
+   marshalEnableCap
+
+foreign import CALLCONV unsafe "glIsEnabled" glIsEnabled ::
+   GLenum -> IO GLboolean
+
+--------------------------------------------------------------------------------
+
+enable :: EnableCap -> Capability -> IO ()
+enable cap state = maybe recordInvalidEnum (f state) (marshalEnableCap cap)
+   where f Disabled = glDisable
+         f Enabled  = glEnable
+
+foreign import CALLCONV unsafe "glDisable" glDisable :: GLenum -> IO ()
+
+foreign import CALLCONV unsafe "glEnable" glEnable :: GLenum -> IO ()
+
+--------------------------------------------------------------------------------
+
+makeStateVarMaybe :: IO EnableCap -> IO a -> (a -> IO ()) -> StateVar (Maybe a)
+makeStateVarMaybe getCap getAct setAct =
+   makeStateVar
+      (getStateVarMaybe getCap getAct)
+      (setStateVarMaybe getCap setAct)
+
+getStateVarMaybe :: IO EnableCap -> IO a -> IO (Maybe a)
+getStateVarMaybe getCap act = do
+   capability <- fmap makeCapability getCap
+   state <- getIO capability
+   if state == Enabled
+      then fmap Just act
+      else return Nothing
+
+setStateVarMaybe :: IO EnableCap -> (a -> IO ()) -> Maybe a -> IO ()
+setStateVarMaybe getCap act val = do
+   capability <- fmap makeCapability getCap
+   maybe (capability $$= Disabled) (\x -> act x >> capability $$= Enabled) val
+   
+     
diff --git a/Graphics/Rendering/OGL/GL/Clipping.hs b/Graphics/Rendering/OGL/GL/Clipping.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Clipping.hs
@@ -0,0 +1,58 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Clipping
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 2.12 (Clipping) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Clipping (
+   ClipPlaneName(..), clipPlane, maxClipPlanes
+) where
+
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Marshal.Utils ( with )
+import Foreign.Ptr ( Ptr, castPtr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum, GLsizei, GLdouble )
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapClipPlane), makeStateVarMaybe )
+import Graphics.Rendering.OGL.GL.CoordTrans ( Plane(..) )
+import Graphics.Rendering.OGL.GL.PeekPoke ( peek1 )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetClipPlane,GetMaxClipPlanes),
+   clipPlaneIndexToEnum, getDoublev, getSizei1 )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar, StateVar )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal ( recordInvalidEnum )
+
+--------------------------------------------------------------------------------
+
+newtype ClipPlaneName = ClipPlaneName GLsizei
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+clipPlane :: ClipPlaneName -> StateVar (Maybe (Plane GLdouble))
+clipPlane (ClipPlaneName i) =
+   makeStateVarMaybe
+      (return (CapClipPlane i))
+      (alloca $ \buf -> do
+          getDoublev (GetClipPlane i) (castPtr buf)
+          peek1 id (buf :: Ptr (Plane GLdouble)))
+      (\plane -> maybe recordInvalidEnum (with plane . glClipPlane)
+                       (clipPlaneIndexToEnum i))
+
+foreign import CALLCONV unsafe "glClipPlane" glClipPlane ::
+   GLenum -> Ptr (Plane GLdouble) -> IO ()
+
+--------------------------------------------------------------------------------
+
+maxClipPlanes :: GettableStateVar GLsizei
+maxClipPlanes = makeGettableStateVar (getSizei1 id GetMaxClipPlanes)
diff --git a/Graphics/Rendering/OGL/GL/ColorSum.hs b/Graphics/Rendering/OGL/GL/ColorSum.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/ColorSum.hs
@@ -0,0 +1,28 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.ColorSum
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.9 (Color Sum) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.ColorSum (
+   colorSum
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapColorSum), makeCapability )
+import Graphics.Rendering.OGL.GL.BasicTypes ( Capability )
+import Graphics.Rendering.OGL.GL.StateVar ( StateVar )
+
+--------------------------------------------------------------------------------
+
+colorSum :: StateVar Capability
+colorSum = makeCapability CapColorSum
diff --git a/Graphics/Rendering/OGL/GL/Colors.hs b/Graphics/Rendering/OGL/GL/Colors.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Colors.hs
@@ -0,0 +1,500 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Colors
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 2.14 (Colors and Coloring) of the
+-- OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Colors (
+   -- * Lighting
+   lighting, Light(..), light, maxLights,
+   FrontFaceDirection(..), frontFace,
+
+   -- * Lighting Parameter Specification
+   Face(..),
+   materialAmbient, materialDiffuse, materialAmbientAndDiffuse,
+   materialSpecular, materialEmission, materialShininess, maxShininess,
+   materialColorIndexes,
+
+   ambient, diffuse, specular,
+   position, spotDirection, spotExponent, maxSpotExponent, spotCutoff,
+   attenuation,
+
+   lightModelAmbient, lightModelLocalViewer, lightModelTwoSide,
+   vertexProgramTwoSide,
+   LightModelColorControl(..), lightModelColorControl,
+
+   -- * ColorMaterial
+   ColorMaterialParameter(..), colorMaterial,
+
+   -- * Flatshading
+   ShadingModel(..), shadeModel
+) where
+
+import Control.Monad ( liftM2, liftM3 )
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Marshal.Array ( allocaArray, withArray )
+import Foreign.Marshal.Utils ( with )
+import Foreign.Ptr ( Ptr )
+import Foreign.Storable ( Storable(peek) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   marshalCapability, unmarshalCapability,
+   EnableCap(CapVertexProgramTwoSide,CapLighting,CapColorMaterial,CapLight),
+   makeCapability,
+   makeStateVarMaybe )
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLenum, GLint, GLsizei, GLfloat,Capability )
+import Graphics.Rendering.OGL.GL.Face (
+   Face(..), marshalFace, unmarshalFace )
+import Graphics.Rendering.OGL.GL.PeekPoke ( peek3 )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetMaxLights, GetFrontFace,GetShadeModel,
+            GetLightModelAmbient, GetLightModelLocalViewer,
+            GetLightModelTwoSide, GetLightModelColorControl,
+            GetColorMaterialFace,GetColorMaterialParameter,
+            GetMaxShininess,GetMaxSpotExponent),
+   getBoolean1, getEnum1, getSizei1, getFloat1, getFloat4, lightIndexToEnum )
+import Graphics.Rendering.OGL.GL.StateVar (
+   getIO, ($$=),
+   GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.VertexSpec (
+   Color4(..), Normal3(..), Vertex4(..), Index1(..) )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal ( recordInvalidEnum )
+
+--------------------------------------------------------------------------------
+
+lighting :: StateVar Capability
+lighting = makeCapability CapLighting
+
+--------------------------------------------------------------------------------
+
+newtype Light = Light GLsizei
+   deriving ( Eq, Ord, Show )
+
+marshalLight :: Light -> Maybe GLenum
+marshalLight (Light l) = lightIndexToEnum l
+
+--------------------------------------------------------------------------------
+
+light :: Light -> StateVar Capability
+light (Light l) = makeCapability (CapLight l)
+
+maxLights :: GettableStateVar GLsizei
+maxLights = makeGettableStateVar (getSizei1 id GetMaxLights)
+
+--------------------------------------------------------------------------------
+
+data FrontFaceDirection =
+     CW
+   | CCW
+   deriving ( Eq, Ord, Show )
+
+marshalFrontFaceDirection :: FrontFaceDirection -> GLenum
+marshalFrontFaceDirection x = case x of
+   CW -> 0x900
+   CCW -> 0x901
+
+unmarshalFrontFaceDirection :: GLenum -> FrontFaceDirection
+unmarshalFrontFaceDirection x
+   | x == 0x900 = CW
+   | x == 0x901 = CCW
+   | otherwise = error ("unmarshalFrontFaceDirection: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+frontFace :: StateVar FrontFaceDirection
+frontFace =
+   makeStateVar
+      (getEnum1 unmarshalFrontFaceDirection GetFrontFace)
+      (glFrontFace . marshalFrontFaceDirection)
+
+foreign import CALLCONV unsafe "glFrontFace" glFrontFace :: GLenum -> IO ()
+
+--------------------------------------------------------------------------------
+
+data MaterialParameter =
+     MaterialEmission
+   | MaterialShininess
+   | MaterialAmbientAndDiffuse
+   | MaterialColorIndexes
+   | MaterialAmbient
+   | MaterialDiffuse
+   | MaterialSpecular
+
+marshalMaterialParameter :: MaterialParameter -> GLenum
+marshalMaterialParameter x = case x of
+   MaterialEmission -> 0x1600
+   MaterialShininess -> 0x1601
+   MaterialAmbientAndDiffuse -> 0x1602
+   MaterialColorIndexes -> 0x1603
+   MaterialAmbient -> 0x1200
+   MaterialDiffuse -> 0x1201
+   MaterialSpecular -> 0x1202
+
+--------------------------------------------------------------------------------
+
+materialAmbient :: Face -> StateVar (Color4 GLfloat)
+materialAmbient =
+   makeMaterialVar glGetMaterialfvc glMaterialfvc MaterialAmbient
+
+materialDiffuse :: Face -> StateVar (Color4 GLfloat)
+materialDiffuse =
+   makeMaterialVar glGetMaterialfvc glMaterialfvc MaterialDiffuse
+
+materialAmbientAndDiffuse :: Face -> StateVar (Color4 GLfloat)
+materialAmbientAndDiffuse =
+   makeMaterialVar glGetMaterialfvc glMaterialfvc MaterialAmbientAndDiffuse
+
+materialSpecular :: Face -> StateVar (Color4 GLfloat)
+materialSpecular =
+   makeMaterialVar glGetMaterialfvc glMaterialfvc MaterialSpecular
+
+materialEmission :: Face -> StateVar (Color4 GLfloat)
+materialEmission =
+   makeMaterialVar glGetMaterialfvc glMaterialfvc MaterialEmission
+
+makeMaterialVar :: Storable a
+                => (GLenum -> GLenum -> Ptr a -> IO ())
+                -> (GLenum -> GLenum -> Ptr a -> IO ())
+                -> MaterialParameter -> Face -> StateVar a
+makeMaterialVar getter setter materialParameter face =
+   makeStateVar (alloca $ \buf -> do getter f mp buf ; peek buf)
+                (\val -> with val $ setter f mp)
+   where mp = marshalMaterialParameter materialParameter
+         f  = marshalFace face
+
+foreign import CALLCONV unsafe "glGetMaterialfv" glGetMaterialfvc ::
+   GLenum -> GLenum -> Ptr (Color4 GLfloat) -> IO ()
+
+foreign import CALLCONV unsafe "glMaterialfv" glMaterialfvc ::
+   GLenum -> GLenum -> Ptr (Color4 GLfloat) -> IO ()
+
+--------------------------------------------------------------------------------
+
+materialShininess :: Face -> StateVar GLfloat
+materialShininess =
+   makeMaterialVar glGetMaterialfvf glMaterialff MaterialShininess
+
+foreign import CALLCONV unsafe "glGetMaterialfv" glGetMaterialfvf ::
+   GLenum -> GLenum -> Ptr GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glMaterialfv" glMaterialff ::
+   GLenum -> GLenum -> Ptr GLfloat -> IO ()
+
+maxShininess :: GettableStateVar GLfloat
+maxShininess = makeGettableStateVar $ getFloat1 id GetMaxShininess
+
+--------------------------------------------------------------------------------
+
+-- Alas, (Index1 GLint, Index1 GLint, Index1 GLint) is not an instance of
+-- Storable...
+
+materialColorIndexes ::
+   Face -> StateVar (Index1 GLint, Index1 GLint, Index1 GLint)
+materialColorIndexes face =
+   makeStateVar (getMaterialColorIndexes face) (setMaterialColorIndexes face)
+
+getMaterialColorIndexes :: Face -> IO (Index1 GLint, Index1 GLint, Index1 GLint)
+getMaterialColorIndexes face =
+   allocaArray 3 $ \buf -> do
+      glGetMaterialiv (marshalFace face)
+                      (marshalMaterialParameter MaterialColorIndexes)
+                      buf
+      peek3 (\a d s -> (Index1 a, Index1 d, Index1 s)) buf
+
+foreign import CALLCONV unsafe "glGetMaterialiv" glGetMaterialiv ::
+   GLenum -> GLenum -> Ptr GLint -> IO ()
+
+setMaterialColorIndexes ::
+   Face -> (Index1 GLint, Index1 GLint, Index1 GLint) -> IO ()
+setMaterialColorIndexes face (Index1 a, Index1 d, Index1 s) =
+   withArray [a, d, s] $
+      glMaterialiv (marshalFace face)
+                   (marshalMaterialParameter MaterialColorIndexes)
+
+foreign import CALLCONV unsafe "glMaterialiv" glMaterialiv ::
+   GLenum -> GLenum -> Ptr GLint -> IO ()
+
+--------------------------------------------------------------------------------
+
+data LightParameter =
+     Ambient'
+   | Diffuse'
+   | Specular'
+   | Position
+   | SpotDirection
+   | SpotExponent
+   | SpotCutoff
+   | ConstantAttenuation
+   | LinearAttenuation
+   | QuadraticAttenuation
+
+marshalLightParameter :: LightParameter -> GLenum
+marshalLightParameter x = case x of
+   Ambient' -> 0x1200
+   Diffuse' -> 0x1201
+   Specular' -> 0x1202
+   Position -> 0x1203
+   SpotDirection -> 0x1204
+   SpotExponent -> 0x1205
+   SpotCutoff -> 0x1206
+   ConstantAttenuation -> 0x1207
+   LinearAttenuation -> 0x1208
+   QuadraticAttenuation -> 0x1209
+
+--------------------------------------------------------------------------------
+
+ambient :: Light -> StateVar (Color4 GLfloat)
+ambient = makeLightVar glGetLightfvc glLightfvc Ambient' black
+
+black :: Color4 GLfloat
+black = Color4 0 0 0 0
+
+diffuse :: Light -> StateVar (Color4 GLfloat)
+diffuse = makeLightVar glGetLightfvc glLightfvc Diffuse' black
+
+specular :: Light -> StateVar (Color4 GLfloat)
+specular = makeLightVar glGetLightfvc glLightfvc Specular' black
+
+makeLightVar :: Storable a
+             => (GLenum -> GLenum -> Ptr a -> IO ())
+             -> (GLenum -> GLenum -> Ptr a -> IO ())
+             -> LightParameter -> a -> Light -> StateVar a
+makeLightVar getter setter lightParameter defaultValue theLight =
+   makeStateVar (maybe (return defaultValue) getLightVar ml)
+                (\val -> maybe recordInvalidEnum (setLightVar val) ml)
+   where lp          = marshalLightParameter lightParameter
+         ml          = marshalLight theLight
+         getLightVar = \l -> alloca $ \buf -> do getter l lp buf ; peek buf
+         setLightVar = \val l -> with val $ setter l lp
+
+foreign import CALLCONV unsafe "glGetLightfv" glGetLightfvc ::
+   GLenum -> GLenum -> Ptr (Color4 GLfloat) -> IO ()
+
+foreign import CALLCONV unsafe "glLightfv" glLightfvc ::
+   GLenum -> GLenum -> Ptr (Color4 GLfloat) -> IO ()
+
+--------------------------------------------------------------------------------
+
+position :: Light -> StateVar (Vertex4 GLfloat)
+position = makeLightVar glGetLightfvv glLightfvv Position (Vertex4 0 0 0 0)
+
+foreign import CALLCONV unsafe "glLightfv" glLightfvv ::
+   GLenum -> GLenum -> Ptr (Vertex4 GLfloat) -> IO ()
+
+foreign import CALLCONV unsafe "glGetLightfv" glGetLightfvv ::
+   GLenum -> GLenum -> Ptr (Vertex4 GLfloat) -> IO ()
+
+--------------------------------------------------------------------------------
+
+spotDirection :: Light -> StateVar (Normal3 GLfloat)
+spotDirection =
+   makeLightVar glGetLightfvn glLightfvn SpotDirection (Normal3 0 0 0)
+
+foreign import CALLCONV unsafe "glLightfv" glLightfvn ::
+   GLenum -> GLenum -> Ptr (Normal3 GLfloat) -> IO ()
+
+foreign import CALLCONV unsafe "glGetLightfv" glGetLightfvn ::
+   GLenum -> GLenum -> Ptr (Normal3 GLfloat) -> IO ()
+
+--------------------------------------------------------------------------------
+
+spotExponent :: Light -> StateVar GLfloat
+spotExponent = makeLightVar glGetLightfv glLightfv SpotExponent 0
+
+foreign import CALLCONV unsafe "glLightfv" glLightfv ::
+   GLenum -> GLenum -> Ptr GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glGetLightfv" glGetLightfv ::
+   GLenum -> GLenum -> Ptr GLfloat -> IO ()
+
+maxSpotExponent :: GettableStateVar GLfloat
+maxSpotExponent = makeGettableStateVar $ getFloat1 id GetMaxSpotExponent
+
+--------------------------------------------------------------------------------
+
+spotCutoff :: Light -> StateVar GLfloat
+spotCutoff = makeLightVar glGetLightfv glLightfv SpotCutoff 0
+
+--------------------------------------------------------------------------------
+
+attenuation :: Light -> StateVar (GLfloat, GLfloat, GLfloat)
+attenuation theLight =
+   makeStateVar
+      (liftM3 (,,) (getIO (constantAttenuation  theLight))
+                   (getIO (linearAttenuation    theLight))
+                   (getIO (quadraticAttenuation theLight)))
+      (\(constant, linear, quadratic) -> do
+         constantAttenuation  theLight $$= constant
+         linearAttenuation    theLight $$= linear
+         quadraticAttenuation theLight $$= quadratic)
+	
+	
+	
+constantAttenuation :: Light -> StateVar GLfloat
+constantAttenuation = makeLightVar glGetLightfv glLightfv ConstantAttenuation 0
+
+linearAttenuation :: Light -> StateVar GLfloat
+linearAttenuation = makeLightVar glGetLightfv glLightfv LinearAttenuation 0
+
+quadraticAttenuation :: Light -> StateVar GLfloat
+quadraticAttenuation =
+   makeLightVar glGetLightfv glLightfv QuadraticAttenuation 0
+
+--------------------------------------------------------------------------------
+
+data LightModelParameter =
+     LightModelAmbient
+   | LightModelLocalViewer
+   | LightModelTwoSide
+   | LightModelColorControl
+
+marshalLightModelParameter :: LightModelParameter -> GLenum
+marshalLightModelParameter x = case x of
+   LightModelAmbient -> 0xb53
+   LightModelLocalViewer -> 0xb51
+   LightModelTwoSide -> 0xb52
+   LightModelColorControl -> 0x81f8
+
+--------------------------------------------------------------------------------
+
+lightModelAmbient :: StateVar (Color4 GLfloat)
+lightModelAmbient =
+   makeStateVar
+      (getFloat4 Color4 GetLightModelAmbient)
+      (\c -> with c $
+                glLightModelfv (marshalLightModelParameter LightModelAmbient))
+
+foreign import CALLCONV unsafe "glLightModelfv" glLightModelfv ::
+   GLenum -> Ptr (Color4 GLfloat) -> IO ()
+
+--------------------------------------------------------------------------------
+
+lightModelLocalViewer :: StateVar Capability
+lightModelLocalViewer =
+   makeLightModelCapVar GetLightModelLocalViewer LightModelLocalViewer
+
+makeLightModelCapVar :: GetPName -> LightModelParameter -> StateVar Capability
+makeLightModelCapVar pname lightModelParameter =
+   makeStateVar
+      (getBoolean1 unmarshalCapability pname)
+      (glLightModeli (marshalLightModelParameter lightModelParameter) .
+                     fromIntegral . marshalCapability)
+
+foreign import CALLCONV unsafe "glLightModeli" glLightModeli ::
+   GLenum -> GLint -> IO ()
+
+--------------------------------------------------------------------------------
+
+lightModelTwoSide :: StateVar Capability
+lightModelTwoSide = makeLightModelCapVar GetLightModelTwoSide LightModelTwoSide
+
+vertexProgramTwoSide :: StateVar Capability
+vertexProgramTwoSide = makeCapability CapVertexProgramTwoSide
+
+--------------------------------------------------------------------------------
+
+data LightModelColorControl =
+     SingleColor
+   | SeparateSpecularColor
+   deriving ( Eq, Ord, Show )
+
+marshalLightModelColorControl :: LightModelColorControl -> GLenum
+marshalLightModelColorControl x = case x of
+   SingleColor -> 0x81f9
+   SeparateSpecularColor -> 0x81fa
+
+unmarshalLightModelColorControl :: GLenum -> LightModelColorControl
+unmarshalLightModelColorControl x
+   | x == 0x81f9 = SingleColor
+   | x == 0x81fa = SeparateSpecularColor
+   | otherwise = error ("unmarshalLightModelColorControl: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+lightModelColorControl :: StateVar LightModelColorControl
+lightModelColorControl =
+   makeStateVar
+      (getEnum1 unmarshalLightModelColorControl GetLightModelColorControl)
+      (glLightModeli (marshalLightModelParameter LightModelColorControl) .
+                     fromIntegral . marshalLightModelColorControl)
+
+--------------------------------------------------------------------------------
+
+data ColorMaterialParameter =
+     Ambient
+   | Diffuse
+   | Specular
+   | Emission
+   | AmbientAndDiffuse
+   deriving ( Eq, Ord, Show )
+
+marshalColorMaterialParameter :: ColorMaterialParameter -> GLenum
+marshalColorMaterialParameter x = case x of
+   Ambient -> 0x1200
+   Diffuse -> 0x1201
+   Specular -> 0x1202
+   Emission -> 0x1600
+   AmbientAndDiffuse -> 0x1602
+
+unmarshalColorMaterialParameter :: GLenum -> ColorMaterialParameter
+unmarshalColorMaterialParameter x
+   | x == 0x1200 = Ambient
+   | x == 0x1201 = Diffuse
+   | x == 0x1202 = Specular
+   | x == 0x1600 = Emission
+   | x == 0x1602 = AmbientAndDiffuse
+   | otherwise = error ("unmarshalColorMaterialParameter: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+colorMaterial :: StateVar (Maybe (Face, ColorMaterialParameter))
+colorMaterial =
+   makeStateVarMaybe
+      (return CapColorMaterial)
+      (liftM2
+         (,)
+         (getEnum1 unmarshalFace GetColorMaterialFace)
+         (getEnum1 unmarshalColorMaterialParameter GetColorMaterialParameter))
+      (\(face, param) -> glColorMaterial (marshalFace face)
+                                         (marshalColorMaterialParameter param))
+
+foreign import CALLCONV unsafe "glColorMaterial" glColorMaterial ::
+   GLenum -> GLenum -> IO ()
+
+--------------------------------------------------------------------------------
+
+data ShadingModel =
+     Flat
+   | Smooth
+   deriving ( Eq, Ord, Show )
+
+marshalShadingModel :: ShadingModel -> GLenum
+marshalShadingModel x = case x of
+   Flat -> 0x1d00
+   Smooth -> 0x1d01
+
+unmarshalShadingModel :: GLenum -> ShadingModel
+unmarshalShadingModel x
+   | x == 0x1d00 = Flat
+   | x == 0x1d01 = Smooth
+   | otherwise = error ("unmarshalShadingModel: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+shadeModel :: StateVar ShadingModel
+shadeModel =
+   makeStateVar
+      (getEnum1 unmarshalShadingModel GetShadeModel)
+      (glShadeModel . marshalShadingModel)
+
+foreign import CALLCONV unsafe "glShadeModel" glShadeModel :: GLenum -> IO ()
diff --git a/Graphics/Rendering/OGL/GL/ComparisonFunction.hs b/Graphics/Rendering/OGL/GL/ComparisonFunction.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/ComparisonFunction.hs
@@ -0,0 +1,58 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.ComparisonFunction
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for (un-)marshaling ComparisonFunction.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.ComparisonFunction (
+   ComparisonFunction(..), marshalComparisonFunction,
+   unmarshalComparisonFunction
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum )
+
+--------------------------------------------------------------------------------
+
+data ComparisonFunction =
+     Never
+   | Less
+   | Equal
+   | Lequal
+   | Greater
+   | Notequal
+   | Gequal
+   | Always
+   deriving ( Eq, Ord, Show )
+
+marshalComparisonFunction :: ComparisonFunction -> GLenum
+marshalComparisonFunction x = case x of
+   Never -> 0x200
+   Less -> 0x201
+   Equal -> 0x202
+   Lequal -> 0x203
+   Greater -> 0x204
+   Notequal -> 0x205
+   Gequal -> 0x206
+   Always -> 0x207
+
+unmarshalComparisonFunction :: GLenum -> ComparisonFunction
+unmarshalComparisonFunction x
+   | x == 0x200 = Never
+   | x == 0x201 = Less
+   | x == 0x202 = Equal
+   | x == 0x203 = Lequal
+   | x == 0x204 = Greater
+   | x == 0x205 = Notequal
+   | x == 0x206 = Gequal
+   | x == 0x207 = Always
+   | otherwise = error ("unmarshalComparisonFunction: illegal value " ++ show x)
diff --git a/Graphics/Rendering/OGL/GL/ControlPoint.hs b/Graphics/Rendering/OGL/GL/ControlPoint.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/ControlPoint.hs
@@ -0,0 +1,164 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.ControlPoint
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for handling control points.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.ControlPoint (
+   ControlPoint(..)
+) where
+
+import Foreign.Ptr ( Ptr )
+import Foreign.Storable ( Storable(peek,poke) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum )
+import Graphics.Rendering.OGL.GL.Capability ( EnableCap(..) )
+import Graphics.Rendering.OGL.GL.Domain ( Domain )
+import Graphics.Rendering.OGL.GL.VertexArrays ( Stride )
+import Graphics.Rendering.OGL.GL.VertexSpec (
+   Vertex3, Vertex4, Index1, Color4, Normal3, TexCoord1, TexCoord2, TexCoord3,
+   TexCoord4 )
+
+--------------------------------------------------------------------------------
+
+class ControlPoint c where
+   map1Target       :: Domain d => c d -> GLenum
+   map2Target       :: Domain d => c d -> GLenum
+   enableCap1       :: Domain d => c d -> EnableCap
+   enableCap2       :: Domain d => c d -> EnableCap
+   numComponents    :: Domain d => c d -> Stride
+   peekControlPoint :: Domain d => Ptr (c d) -> IO (c d)
+   pokeControlPoint :: Domain d => Ptr (c d) -> (c d) -> IO ()
+
+instance ControlPoint Vertex3 where
+   map1Target       = marshalMapTarget . const Map1Vertex3
+   map2Target       = marshalMapTarget . const Map2Vertex3
+   enableCap1       = const CapMap1Vertex3
+   enableCap2       = const CapMap2Vertex3
+   numComponents    = const 3
+   peekControlPoint = peek
+   pokeControlPoint = poke
+
+instance ControlPoint Vertex4 where
+   map1Target       = marshalMapTarget . const Map1Vertex4
+   map2Target       = marshalMapTarget . const Map2Vertex4
+   enableCap1       = const CapMap1Vertex4
+   enableCap2       = const CapMap2Vertex4
+   numComponents    = const 4
+   peekControlPoint = peek
+   pokeControlPoint = poke
+
+instance ControlPoint Index1 where
+   map1Target       = marshalMapTarget . const Map1Index
+   map2Target       = marshalMapTarget . const Map2Index
+   enableCap1       = const CapMap1Index
+   enableCap2       = const CapMap2Index
+   numComponents    = const 1
+   peekControlPoint = peek
+   pokeControlPoint = poke
+
+instance ControlPoint Color4 where
+   map1Target       = marshalMapTarget . const Map1Color4
+   map2Target       = marshalMapTarget . const Map2Color4
+   enableCap1       = const CapMap1Color4
+   enableCap2       = const CapMap2Color4
+   numComponents    = const 4
+   peekControlPoint = peek
+   pokeControlPoint = poke
+
+instance ControlPoint Normal3 where
+   map1Target       = marshalMapTarget . const Map1Normal
+   map2Target       = marshalMapTarget . const Map2Normal
+   enableCap1       = const CapMap1Normal
+   enableCap2       = const CapMap2Normal
+   numComponents    = const 3
+   peekControlPoint = peek
+   pokeControlPoint = poke
+
+instance ControlPoint TexCoord1 where
+   map1Target       = marshalMapTarget . const Map1TextureCoord1
+   map2Target       = marshalMapTarget . const Map2TextureCoord1
+   enableCap1       = const CapMap1TextureCoord1
+   enableCap2       = const CapMap2TextureCoord1
+   numComponents    = const 1
+   peekControlPoint = peek
+   pokeControlPoint = poke
+
+instance ControlPoint TexCoord2 where
+   map1Target       = marshalMapTarget . const Map1TextureCoord2
+   map2Target       = marshalMapTarget . const Map2TextureCoord2
+   enableCap1       = const CapMap1TextureCoord2
+   enableCap2       = const CapMap2TextureCoord2
+   numComponents    = const 2
+   peekControlPoint = peek
+   pokeControlPoint = poke
+
+instance ControlPoint TexCoord3 where
+   map1Target       = marshalMapTarget . const Map1TextureCoord3
+   map2Target       = marshalMapTarget . const Map2TextureCoord3
+   enableCap1       = const CapMap1TextureCoord3
+   enableCap2       = const CapMap2TextureCoord3
+   numComponents    = const 3
+   peekControlPoint = peek
+   pokeControlPoint = poke
+
+instance ControlPoint TexCoord4 where
+   map1Target       = marshalMapTarget . const Map1TextureCoord4
+   map2Target       = marshalMapTarget . const Map2TextureCoord4
+   enableCap1       = const CapMap1TextureCoord4
+   enableCap2       = const CapMap2TextureCoord4
+   numComponents    = const 4
+   peekControlPoint = peek
+   pokeControlPoint = poke
+
+--------------------------------------------------------------------------------
+
+data MapTarget =
+     Map1Color4
+   | Map1Index
+   | Map1Normal
+   | Map1TextureCoord1
+   | Map1TextureCoord2
+   | Map1TextureCoord3
+   | Map1TextureCoord4
+   | Map1Vertex3
+   | Map1Vertex4
+   | Map2Color4
+   | Map2Index
+   | Map2Normal
+   | Map2TextureCoord1
+   | Map2TextureCoord2
+   | Map2TextureCoord3
+   | Map2TextureCoord4
+   | Map2Vertex3
+   | Map2Vertex4
+
+marshalMapTarget :: MapTarget -> GLenum
+marshalMapTarget x = case x of
+   Map1Color4 -> 0xd90
+   Map1Index -> 0xd91
+   Map1Normal -> 0xd92
+   Map1TextureCoord1 -> 0xd93
+   Map1TextureCoord2 -> 0xd94
+   Map1TextureCoord3 -> 0xd95
+   Map1TextureCoord4 -> 0xd96
+   Map1Vertex3 -> 0xd97
+   Map1Vertex4 -> 0xd98
+   Map2Color4 -> 0xdb0
+   Map2Index -> 0xdb1
+   Map2Normal -> 0xdb2
+   Map2TextureCoord1 -> 0xdb3
+   Map2TextureCoord2 -> 0xdb4
+   Map2TextureCoord3 -> 0xdb5
+   Map2TextureCoord4 -> 0xdb6
+   Map2Vertex3 -> 0xdb7
+   Map2Vertex4 -> 0xdb8
diff --git a/Graphics/Rendering/OGL/GL/CoordTrans.hs b/Graphics/Rendering/OGL/GL/CoordTrans.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/CoordTrans.hs
@@ -0,0 +1,625 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.CoordTrans
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 2.11 (Coordinate Transformations) of the
+-- OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.CoordTrans (
+   -- * Controlling the Viewport
+   depthRange,
+   Position(..), Size(..), viewport, maxViewportDims,
+
+   -- * Matrices
+   MatrixMode(..), matrixMode,
+   Vector2(..), Vector3(..),
+   MatrixOrder(..), MatrixComponent(rotate,translate,scale), Matrix(..),
+   currentMatrix, matrix, multMatrix, GLmatrix, loadIdentity,
+   ortho, frustum, depthClamp,
+   activeTexture,
+   preservingMatrix, unsafePreservingMatrix,
+   stackDepth, maxStackDepth,
+
+   -- * Normal Transformation
+   rescaleNormal, normalize,
+
+   -- * Generating Texture Coordinates
+   Plane(..), TextureCoordName(..), TextureGenMode(..), textureGenMode
+) where
+
+import Foreign.ForeignPtr ( ForeignPtr, mallocForeignPtrArray, withForeignPtr )
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Marshal.Array ( allocaArray, peekArray, pokeArray, withArray )
+import Foreign.Marshal.Utils ( with )
+import Foreign.Ptr ( Ptr, castPtr )
+import Foreign.Storable ( Storable(..) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapRescaleNormal, CapNormalize,CapDepthClamp,
+             CapTextureGenS, CapTextureGenT,
+             CapTextureGenR, CapTextureGenQ),
+   makeCapability, makeStateVarMaybe )
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLenum, GLint, GLsizei, GLfloat, GLdouble, GLclampd, Capability(..) )
+import Graphics.Rendering.OGL.GL.Exception ( bracket, unsafeBracket_ )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.PeekPoke (
+   peek1, peek2, peek3, peek4, poke2, poke3, poke4 )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetDepthRange,GetViewport,GetMaxViewportDims,GetMatrixMode,
+            GetModelviewMatrix,GetProjectionMatrix,
+            GetTextureMatrix, GetColorMatrix,GetMatrixPalette,GetActiveTexture,
+            GetCurrentMatrixStackDepth,GetModelviewStackDepth,
+            GetMaxModelviewStackDepth,GetProjectionStackDepth,
+            GetMaxProjectionStackDepth,GetTextureStackDepth,
+            GetMaxTextureStackDepth,GetColorMatrixStackDepth,
+            GetMaxColorMatrixStackDepth,GetMaxMatrixPaletteStackDepth),
+   getInteger2, getInteger4, getEnum1, getSizei1, getFloatv,
+   getDouble2, getDoublev, modelviewIndexToEnum, modelviewEnumToIndex )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar, getIO, ($$=),
+   StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.Texturing.TextureUnit (
+   marshalTextureUnit, unmarshalTextureUnit )
+import Graphics.Rendering.OGL.GL.VertexSpec ( TextureUnit )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal (
+   recordInvalidEnum, recordInvalidValue )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+#include "HsOpenGLTypes.h"
+
+--------------------------------------------------------------------------------
+
+-- | After clipping and division by /w/, depth coordinates range from -1 to 1,
+-- corresponding to the near and far clipping planes. 'depthRange' specifies a
+-- linear mapping of the normalized depth coordinates in this range to window
+-- depth coordinates. Regardless of the actual depth buffer implementation,
+-- window coordinate depth values are treated as though they range from 0
+-- through 1 (like color components). Thus, the values accepted by 'depthRange'
+-- are both clamped to this range before they are accepted.
+--
+-- The initial setting of (0, 1) maps the near plane to 0 and the far plane to
+-- 1. With this mapping, the depth buffer range is fully utilized.
+--
+-- It is not necessary that the near value be less than the far value. Reverse
+-- mappings such as (1, 0) are acceptable.
+
+depthRange :: StateVar (GLclampd, GLclampd)
+depthRange = makeStateVar (getDouble2 (,) GetDepthRange) (uncurry glDepthRange)
+
+foreign import CALLCONV unsafe "glDepthRange" glDepthRange ::
+   GLclampd -> GLclampd -> IO ()
+
+--------------------------------------------------------------------------------
+
+-- | A 2-dimensional position, measured in pixels.
+data Position = Position !GLint !GLint
+   deriving ( Eq, Ord, Show )
+
+-- | A 2-dimensional size, measured in pixels.
+data Size = Size !GLsizei !GLsizei
+   deriving ( Eq, Ord, Show )
+
+-- | Controls the affine transformation from normalized device coordinates to
+-- window coordinates. The viewport state variable consists of the coordinates
+-- (/x/, /y/) of the lower left corner of the viewport rectangle, (in pixels,
+-- initial value (0,0)), and the size (/width/, /height/) of the viewport. When
+-- a GL context is first attached to a window, /width/ and /height/ are set to
+-- the dimensions of that window.
+--
+-- Let (/xnd/, /ynd/) be normalized device coordinates. Then the window
+-- coordinates (/xw/, /yw/) are computed as follows:
+--
+-- /xw/ = (/xnd/ + 1) (/width/  \/ 2) + /x/
+--
+-- /yw/ = (/ynd/ + 1) (/heigth/ \/ 2) + /y/
+--
+-- Viewport width and height are silently clamped to a range that depends on the
+-- implementation, see 'maxViewportDims'.
+
+viewport :: StateVar (Position, Size)
+viewport = makeStateVar (getInteger4 makeVp GetViewport)
+                        (\(Position x y, Size w h) -> glViewport x y w h)
+   where makeVp x y w h = (Position x y, Size (fromIntegral w) (fromIntegral h))
+
+foreign import CALLCONV unsafe "glViewport" glViewport ::
+   GLint -> GLint -> GLsizei -> GLsizei -> IO ()
+
+-- | The implementation-dependent maximum viewport width and height.
+
+maxViewportDims :: GettableStateVar Size
+maxViewportDims = makeGettableStateVar (getInteger2 Size GetMaxViewportDims)
+
+--------------------------------------------------------------------------------
+
+-- | A matrix stack.
+
+data MatrixMode =
+     Modelview GLsizei  -- ^ The modelview matrix stack of the specified vertex unit.
+   | Projection         -- ^ The projection matrix stack.
+   | Texture            -- ^ The texture matrix stack.
+   | Color              -- ^ The color matrix stack.
+   | MatrixPalette      -- ^ The matrix palette stack.
+   deriving ( Eq, Ord, Show )
+
+marshalMatrixMode :: MatrixMode -> Maybe GLenum
+marshalMatrixMode x = case x of
+   Modelview i -> modelviewIndexToEnum i
+   Projection -> Just 0x1701
+   Texture -> Just 0x1702
+   Color -> Just 0x1800
+   MatrixPalette -> Just 0x8840
+
+unmarshalMatrixMode :: GLenum -> MatrixMode
+unmarshalMatrixMode x
+   | x == 0x1701 = Projection
+   | x == 0x1702 = Texture
+   | x == 0x1800 = Color
+   | x == 0x8840 = MatrixPalette
+   | otherwise =
+        case modelviewEnumToIndex x of
+           Just i -> Modelview i
+           Nothing -> error ("unmarshalMatrixMode: illegal value " ++ show x)
+
+matrixModeToGetMatrix :: MatrixMode -> GetPName
+matrixModeToGetMatrix x = case x of
+   Modelview _   -> GetModelviewMatrix -- ???
+   Projection    -> GetProjectionMatrix
+   Texture       -> GetTextureMatrix
+   Color         -> GetColorMatrix
+   MatrixPalette -> GetMatrixPalette
+
+matrixModeToGetStackDepth :: MatrixMode -> GetPName
+matrixModeToGetStackDepth x =  case x of
+   Modelview _   -> GetModelviewStackDepth
+   Projection    -> GetProjectionStackDepth
+   Texture       -> GetTextureStackDepth
+   Color         -> GetColorMatrixStackDepth
+   MatrixPalette -> error "matrixModeToGetStackDepth: impossible"
+
+matrixModeToGetMaxStackDepth :: MatrixMode -> GetPName
+matrixModeToGetMaxStackDepth x = case x of
+   Modelview _    -> GetMaxModelviewStackDepth
+   Projection     -> GetMaxProjectionStackDepth
+   Texture        -> GetMaxTextureStackDepth
+   Color          -> GetMaxColorMatrixStackDepth
+   MatrixPalette  -> GetMaxMatrixPaletteStackDepth
+
+--------------------------------------------------------------------------------
+
+-- | Controls which matrix stack is the target for subsequent matrix operations.
+-- The initial value is ('Modelview' 0).
+
+matrixMode :: StateVar MatrixMode
+matrixMode =
+   makeStateVar (getEnum1 unmarshalMatrixMode GetMatrixMode)
+                (maybe recordInvalidValue glMatrixMode . marshalMatrixMode)
+
+foreign import CALLCONV unsafe "glMatrixMode" glMatrixMode :: GLenum -> IO ()
+
+--------------------------------------------------------------------------------
+
+data Vector2 a = Vector2 !a !a
+   deriving ( Eq, Ord, Show )
+
+instance Storable a => Storable (Vector2 a) where
+   sizeOf    ~(Vector2 x _) = 2 * sizeOf x
+   alignment ~(Vector2 x _) = alignment x
+   peek                     = peek2 Vector2 . castPtr
+   poke ptr   (Vector2 x y) = poke2 (castPtr ptr) x y
+
+--------------------------------------------------------------------------------
+
+data Vector3 a = Vector3 !a !a !a
+   deriving ( Eq, Ord, Show )
+
+instance Storable a => Storable (Vector3 a) where
+   sizeOf    ~(Vector3 x _ _) = 3 * sizeOf x
+   alignment ~(Vector3 x _ _) = alignment x
+   peek                       = peek3 Vector3 . castPtr
+   poke ptr   (Vector3 x y z) = poke3 (castPtr ptr) x y z
+
+--------------------------------------------------------------------------------
+
+data MatrixOrder = ColumnMajor | RowMajor
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+class Storable c => MatrixComponent c where
+   getMatrix :: GetPName -> Ptr c -> GL ()
+   loadMatrix :: Ptr c -> GL ()
+   loadTransposeMatrix :: Ptr c -> GL ()
+   multMatrix_ :: Ptr c -> GL ()
+   multTransposeMatrix :: Ptr c -> GL ()
+   rotate :: c -> Vector3 c -> GL ()
+   translate :: Vector3 c -> GL ()
+   scale :: c -> c -> c -> GL ()
+
+instance MatrixComponent GLfloat_ where
+   getMatrix x y = liftIO (getFloatv x y)
+   loadMatrix = glLoadMatrixf
+   loadTransposeMatrix = glLoadTransposeMatrixfARB
+   multMatrix_ = glMultMatrixf
+   multTransposeMatrix = glMultTransposeMatrixfARB
+   rotate a (Vector3 x y z) = glRotatef a x y z
+   translate (Vector3 x y z) = glTranslatef x y z
+   scale = glScalef
+
+instance MatrixComponent GLdouble_ where
+   getMatrix x y = liftIO (getDoublev x y)
+   loadMatrix = glLoadMatrixd
+   loadTransposeMatrix = glLoadTransposeMatrixdARB
+   multMatrix_ = glMultMatrixd
+   multTransposeMatrix = glMultTransposeMatrixdARB
+   rotate a (Vector3 x y z) = glRotated a x y z
+   translate (Vector3 x y z) = glTranslated x y z
+   scale = glScaled
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glLoadMatrixf" glLoadMatrixf :: Ptr GLfloat -> GL ()
+foreign import CALLCONV unsafe "glLoadMatrixd" glLoadMatrixd :: Ptr GLdouble -> GL ()
+
+EXTENSION_ENTRY("GL_ARB_transpose_matrix or OpenGL 1.3",glLoadTransposeMatrixfARB,Ptr GLfloat -> GL ())
+EXTENSION_ENTRY("GL_ARB_transpose_matrix or OpenGL 1.3",glLoadTransposeMatrixdARB,Ptr GLdouble -> GL ())
+
+foreign import CALLCONV unsafe "glMultMatrixf" glMultMatrixf :: Ptr GLfloat -> GL ()
+foreign import CALLCONV unsafe "glMultMatrixd" glMultMatrixd :: Ptr GLdouble -> GL ()
+
+EXTENSION_ENTRY("GL_ARB_transpose_matrix or OpenGL 1.3",glMultTransposeMatrixfARB,Ptr GLfloat -> GL ())
+EXTENSION_ENTRY("GL_ARB_transpose_matrix or OpenGL 1.3",glMultTransposeMatrixdARB,Ptr GLdouble -> GL ())
+
+foreign import CALLCONV unsafe "glRotatef" glRotatef :: GLfloat -> GLfloat -> GLfloat -> GLfloat -> GL ()
+foreign import CALLCONV unsafe "glRotated" glRotated :: GLdouble -> GLdouble -> GLdouble -> GLdouble -> GL ()
+
+foreign import CALLCONV unsafe "glTranslatef" glTranslatef :: GLfloat -> GLfloat -> GLfloat -> GL ()
+foreign import CALLCONV unsafe "glTranslated" glTranslated :: GLdouble -> GLdouble -> GLdouble -> GL ()
+
+foreign import CALLCONV unsafe "glScalef" glScalef :: GLfloat -> GLfloat -> GLfloat -> GL ()
+foreign import CALLCONV unsafe "glScaled" glScaled :: GLdouble -> GLdouble -> GLdouble -> GL ()
+
+--------------------------------------------------------------------------------
+
+class Matrix m where
+   -- | Create a new matrix of the given order (containing undefined elements)
+   -- and call the action to fill it with 4x4 elements.
+   withNewMatrix ::
+      MatrixComponent c => MatrixOrder -> (Ptr c -> GL ()) -> GL (m c)
+
+   -- | Call the action with the given matrix. /Note:/ The action is /not/
+   -- allowed to modify the matrix elements!
+   withMatrix ::
+      MatrixComponent c => m c -> (MatrixOrder -> Ptr c -> GL a) -> GL a
+
+   newMatrix :: MatrixComponent c => MatrixOrder -> [c] -> GL (m c)
+   getMatrixComponents :: MatrixComponent c => MatrixOrder -> m c -> GL [c]
+
+   withNewMatrix order act = liftIO $ 
+      allocaArray 16 $ \p -> do
+         runGL $ act p
+         components <- peekArray 16 p
+         runGL $ newMatrix order components
+
+   withMatrix mat act = do
+      components <- getMatrixComponents ColumnMajor mat
+      liftIO $ withArray components (runGL . act ColumnMajor)
+
+   newMatrix order components =
+      withNewMatrix order (liftIO . (flip pokeArray (take 16 components)))
+
+   getMatrixComponents desiredOrder mat =
+      withMatrix mat $ \order p -> liftIO $ 
+        if desiredOrder == order
+           then peekArray 16 p
+           else mapM (peekElemOff p) [ 0, 4,  8, 12,
+                                       1, 5,  9, 13,
+                                       2, 6, 10, 14,
+                                       3, 7, 11, 15 ]
+
+--------------------------------------------------------------------------------
+
+{-# DEPRECATED currentMatrix "use `matrix' instead" #-}
+currentMatrix :: (Matrix m, MatrixComponent c) => StateVar (m c)
+currentMatrix = matrix Nothing
+
+matrix :: (Matrix m, MatrixComponent c) => Maybe MatrixMode -> StateVar (m c)
+matrix maybeMode =
+   makeStateVar
+      (maybe (getIO matrixMode) return maybeMode >>= (getMatrix' . matrixModeToGetMatrix))
+      (maybe id withMatrixMode maybeMode . setMatrix)
+
+withMatrixMode :: MatrixMode -> IO a -> IO a
+withMatrixMode mode act =
+   preservingMatrixMode $ do
+      matrixMode $$= mode
+      act
+
+getMatrix' :: (Matrix m, MatrixComponent c) => GetPName -> IO (m c)
+getMatrix' = runGL . withNewMatrix ColumnMajor . getMatrix
+
+setMatrix :: (Matrix m, MatrixComponent c) => m c -> IO ()
+setMatrix mat = runGL $
+   withMatrix mat $ \order ->
+      case order of
+         ColumnMajor -> loadMatrix
+         RowMajor    -> loadTransposeMatrix
+
+multMatrix :: (Matrix m, MatrixComponent c) => m c -> GL ()
+multMatrix mat = 
+   withMatrix mat $ \order ->
+      case order of
+         ColumnMajor -> multMatrix_
+         RowMajor    -> multTransposeMatrix
+
+--------------------------------------------------------------------------------
+
+data GLmatrix a = GLmatrix MatrixOrder (ForeignPtr a)
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq (GLmatrix a)
+instance Ord (GLmatrix a)
+instance Show (GLmatrix a)
+#else
+   deriving ( Eq, Ord, Show )
+#endif
+
+instance Matrix GLmatrix where
+   withNewMatrix order f = do
+      fp <- liftIO $ mallocForeignPtrArray 16
+      liftIO $ withForeignPtr fp (runGL . f)
+      return $ GLmatrix order fp
+
+   withMatrix (GLmatrix order fp) f = liftIO $ withForeignPtr fp (runGL . f order)
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glLoadIdentity" loadIdentity :: GL ()
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glOrtho" ortho ::
+   GLdouble -> GLdouble -> GLdouble -> GLdouble -> GLdouble -> GLdouble -> GL ()
+
+foreign import CALLCONV unsafe "glFrustum" frustum ::
+   GLdouble -> GLdouble -> GLdouble -> GLdouble -> GLdouble -> GLdouble -> GL ()
+
+--------------------------------------------------------------------------------
+
+depthClamp :: StateVar Capability
+depthClamp = makeCapability CapDepthClamp
+
+--------------------------------------------------------------------------------
+
+activeTexture :: StateVar TextureUnit
+activeTexture = makeStateVar (getEnum1 unmarshalTextureUnit GetActiveTexture)
+                             (glActiveTextureARB . marshalTextureUnit)
+
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glActiveTextureARB,GLenum -> IO ())   
+
+--------------------------------------------------------------------------------
+
+-- | Push the current matrix stack down by one, duplicating the current matrix,
+-- excute the given action, and pop the current matrix stack, replacing the
+-- current matrix with the one below it on the stack (i.e. restoring it to its
+-- previous state). The returned value is that of the given action. Note that
+-- a round-trip to the server is probably required. For a more efficient
+-- version, see 'unsafePreservingMatrix'.
+
+preservingMatrix :: GL a -> GL a
+preservingMatrix = unsafePreservingMatrix . liftIO . preservingMatrixMode . runGL
+
+-- performance paranoia: No (un-)marshaling by avoiding matrixMode
+preservingMatrixMode :: IO a -> IO a
+preservingMatrixMode = bracket (getEnum1 id GetMatrixMode) glMatrixMode . const
+
+-- | A more efficient, but potentially dangerous version of 'preservingMatrix':
+-- The given action is not allowed to throw an exception or change the
+-- current matrix mode permanently.
+
+unsafePreservingMatrix :: GL a -> GL a
+unsafePreservingMatrix x = liftIO $ unsafeBracket_ glPushMatrix glPopMatrix (runGL x)
+
+foreign import CALLCONV unsafe "glPushMatrix" glPushMatrix :: IO ()
+
+foreign import CALLCONV unsafe "glPopMatrix" glPopMatrix :: IO ()
+
+--------------------------------------------------------------------------------
+
+stackDepth :: Maybe MatrixMode -> GettableStateVar GLsizei
+stackDepth maybeMode =
+   makeGettableStateVar $
+      case maybeMode of
+         Nothing -> getSizei1 id GetCurrentMatrixStackDepth -- only with ARB_fragment_program
+         Just MatrixPalette -> do recordInvalidEnum ; return 0
+         Just mode -> getSizei1 id (matrixModeToGetStackDepth mode)
+
+maxStackDepth :: MatrixMode -> GettableStateVar GLsizei
+maxStackDepth =
+   makeGettableStateVar . getSizei1 id . matrixModeToGetMaxStackDepth
+
+--------------------------------------------------------------------------------
+
+-- | If 'rescaleNormal' contains 'Enabled', normal vectors specified with
+-- 'Graphics.Rendering.OGL.GL.VertexSpec.normal' are scaled by a scaling
+-- factor derived from the modelview matrix. 'rescaleNormal' requires that the
+-- originally specified normals were of unit length, and that the modelview
+-- matrix contains only uniform scales for proper results. The initial value of
+-- 'rescaleNormal' is 'Disabled'.
+
+rescaleNormal :: StateVar Capability
+rescaleNormal = makeCapability CapRescaleNormal
+
+-- | If 'normalize' contains 'Enabled', normal vectors specified with
+-- 'Graphics.Rendering.OGL.GL.VertexSpec.normal' are scaled to unit length
+-- after transformation. The initial value of 'normalize' is 'Disabled'.
+
+normalize :: StateVar Capability
+normalize = makeCapability CapNormalize
+
+--------------------------------------------------------------------------------
+
+data Plane a = Plane !a !a !a !a
+   deriving ( Eq, Ord, Show )
+
+instance Storable a => Storable (Plane a) where
+   sizeOf    ~(Plane a _ _ _) = 4 * sizeOf a
+   alignment ~(Plane a _ _ _) = alignment a
+   peek                       = peek4 Plane . castPtr
+   poke ptr   (Plane a b c d) = poke4 (castPtr ptr) a b c d
+
+--------------------------------------------------------------------------------
+
+data TextureCoordName =
+     S
+   | T
+   | R
+   | Q
+   deriving ( Eq, Ord, Show )
+
+marshalTextureCoordName :: TextureCoordName -> GLenum
+marshalTextureCoordName x = case x of
+   S -> 0x2000
+   T -> 0x2001
+   R -> 0x2002
+   Q -> 0x2003
+
+--------------------------------------------------------------------------------
+
+data TextureGenParameter =
+     TextureGenMode
+   | ObjectPlane
+   | EyePlane
+
+marshalTextureGenParameter :: TextureGenParameter -> GLenum
+marshalTextureGenParameter x = case x of
+   TextureGenMode -> 0x2500
+   ObjectPlane -> 0x2501
+   EyePlane -> 0x2502
+
+--------------------------------------------------------------------------------
+
+data TextureGenMode' =
+     EyeLinear'
+   | ObjectLinear'
+   | SphereMap'
+   | NormalMap'
+   | ReflectionMap'
+
+marshalTextureGenMode' :: TextureGenMode' -> GLint
+marshalTextureGenMode' x = case x of
+   EyeLinear' -> 0x2400
+   ObjectLinear' -> 0x2401
+   SphereMap' -> 0x2402
+   NormalMap' -> 0x8511
+   ReflectionMap' -> 0x8512
+
+unmarshalTextureGenMode' :: GLint -> TextureGenMode'
+unmarshalTextureGenMode' x
+   | x == 0x2400 = EyeLinear'
+   | x == 0x2401 = ObjectLinear'
+   | x == 0x2402 = SphereMap'
+   | x == 0x8511 = NormalMap'
+   | x == 0x8512 = ReflectionMap'
+   | otherwise = error ("unmarshalTextureGenMode': illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+data TextureGenMode =
+     EyeLinear    (Plane GLdouble)
+   | ObjectLinear (Plane GLdouble)
+   | SphereMap
+   | NormalMap
+   | ReflectionMap
+   deriving ( Eq, Ord, Show )
+
+marshalTextureGenMode :: TextureGenMode -> GLint
+marshalTextureGenMode = marshalTextureGenMode' . convertMode
+   where convertMode (EyeLinear    _) = EyeLinear'
+         convertMode (ObjectLinear _) = ObjectLinear'
+         convertMode SphereMap        = SphereMap'
+         convertMode NormalMap        = NormalMap'
+         convertMode ReflectionMap    = ReflectionMap'
+
+--------------------------------------------------------------------------------
+
+textureGenMode :: TextureCoordName -> StateVar (Maybe TextureGenMode)
+textureGenMode coord =
+   makeStateVarMaybe
+      (return $ textureCoordNameToEnableCap coord)
+      (do mode <- getMode coord
+          case mode of
+             EyeLinear'     -> fmap EyeLinear $ getPlane coord EyePlane
+             ObjectLinear'  -> fmap ObjectLinear $ getPlane coord ObjectPlane
+             SphereMap'     -> return SphereMap
+             NormalMap'     -> return NormalMap
+             ReflectionMap' -> return ReflectionMap)
+      (\mode -> do
+         setMode coord mode
+         case mode of
+            EyeLinear    plane -> setPlane coord EyePlane    plane
+            ObjectLinear plane -> setPlane coord ObjectPlane plane
+            _ -> return ())
+
+--------------------------------------------------------------------------------
+
+textureCoordNameToEnableCap :: TextureCoordName -> EnableCap
+textureCoordNameToEnableCap coord = case coord of
+   S -> CapTextureGenS
+   T -> CapTextureGenT
+   R -> CapTextureGenR
+   Q -> CapTextureGenQ
+
+--------------------------------------------------------------------------------
+
+getMode :: TextureCoordName -> IO TextureGenMode'
+getMode coord = alloca $ \buf -> do
+   glGetTexGeniv (marshalTextureCoordName coord)
+                 (marshalTextureGenParameter TextureGenMode)
+                 buf
+   peek1 unmarshalTextureGenMode' buf
+
+foreign import CALLCONV unsafe "glGetTexGeniv" glGetTexGeniv ::
+   GLenum -> GLenum -> Ptr GLint -> IO ()
+
+setMode :: TextureCoordName -> TextureGenMode -> IO ()
+setMode coord mode =
+   glTexGeni (marshalTextureCoordName coord)
+             (marshalTextureGenParameter TextureGenMode)
+             (marshalTextureGenMode mode)
+
+foreign import CALLCONV unsafe "glTexGeni" glTexGeni ::
+    GLenum -> GLenum -> GLint -> IO ()
+
+--------------------------------------------------------------------------------
+
+getPlane :: TextureCoordName -> TextureGenParameter -> IO (Plane GLdouble)
+getPlane coord param = alloca $ \planeBuffer -> do
+   glGetTexGendv (marshalTextureCoordName coord)
+                 (marshalTextureGenParameter param)
+                 planeBuffer
+   peek planeBuffer
+
+foreign import CALLCONV unsafe "glGetTexGendv" glGetTexGendv ::
+   GLenum -> GLenum -> Ptr (Plane GLdouble) -> IO ()
+
+setPlane :: TextureCoordName -> TextureGenParameter -> Plane GLdouble -> IO ()
+setPlane coord param plane =
+   with plane $ \planeBuffer ->
+      glTexGendv (marshalTextureCoordName coord)
+                 (marshalTextureGenParameter param)
+                 planeBuffer
+
+foreign import CALLCONV unsafe "glTexGendv" glTexGendv ::
+   GLenum -> GLenum -> Ptr (Plane GLdouble) -> IO ()
diff --git a/Graphics/Rendering/OGL/GL/DataType.hs b/Graphics/Rendering/OGL/GL/DataType.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/DataType.hs
@@ -0,0 +1,113 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.DataType
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for (un-)marshaling DataType.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.DataType (
+   DataType(..), marshalDataType, unmarshalDataType
+) where
+
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum )
+
+--------------------------------------------------------------------------------
+
+data DataType =
+     Byte
+   | UnsignedByte
+   | Short
+   | UnsignedShort
+   | Int
+   | UnsignedInt
+   | Float
+   | TwoBytes
+   | ThreeBytes
+   | FourBytes
+   | Double
+   | Bitmap
+   | UnsignedByte332
+   | UnsignedShort4444
+   | UnsignedShort5551
+   | UnsignedInt8888
+   | UnsignedInt1010102
+   | UnsignedByte233Rev
+   | UnsignedShort565
+   | UnsignedShort565Rev
+   | UnsignedShort4444Rev
+   | UnsignedShort1555Rev
+   | UnsignedInt8888Rev
+   | UnsignedInt2101010Rev
+   | UnsignedShort88
+   | UnsignedShort88Rev
+   | UnsignedInt248
+   deriving ( Eq, Ord, Show )
+
+marshalDataType :: DataType -> GLenum
+marshalDataType x = case x of
+   Byte -> 0x1400
+   UnsignedByte -> 0x1401
+   Short -> 0x1402
+   UnsignedShort -> 0x1403
+   Int -> 0x1404
+   UnsignedInt -> 0x1405
+   Float -> 0x1406
+   TwoBytes -> 0x1407
+   ThreeBytes -> 0x1408
+   FourBytes -> 0x1409
+   Double -> 0x140a
+   Bitmap -> 0x1a00
+   UnsignedByte332 -> 0x8032
+   UnsignedShort4444 -> 0x8033
+   UnsignedShort5551 -> 0x8034
+   UnsignedInt8888 -> 0x8035
+   UnsignedInt1010102 -> 0x8036
+   UnsignedByte233Rev -> 0x8362
+   UnsignedShort565 -> 0x8363
+   UnsignedShort565Rev -> 0x8364
+   UnsignedShort4444Rev -> 0x8365
+   UnsignedShort1555Rev -> 0x8366
+   UnsignedInt8888Rev -> 0x8367
+   UnsignedInt2101010Rev -> 0x8368
+   UnsignedShort88 -> 0x85ba
+   UnsignedShort88Rev -> 0x85bb
+   UnsignedInt248 -> 0x84fa
+
+unmarshalDataType :: GLenum -> DataType
+unmarshalDataType x
+   | x == 0x1400 = Byte
+   | x == 0x1401 = UnsignedByte
+   | x == 0x1402 = Short
+   | x == 0x1403 = UnsignedShort
+   | x == 0x1404 = Int
+   | x == 0x1405 = UnsignedInt
+   | x == 0x1406 = Float
+   | x == 0x1407 = TwoBytes
+   | x == 0x1408 = ThreeBytes
+   | x == 0x1409 = FourBytes
+   | x == 0x140a = Double
+   | x == 0x1a00 = Bitmap
+   | x == 0x8032 = UnsignedByte332
+   | x == 0x8033 = UnsignedShort4444
+   | x == 0x8034 = UnsignedShort5551
+   | x == 0x8035 = UnsignedInt8888
+   | x == 0x8036 = UnsignedInt1010102
+   | x == 0x8362 = UnsignedByte233Rev
+   | x == 0x8363 = UnsignedShort565
+   | x == 0x8364 = UnsignedShort565Rev
+   | x == 0x8365 = UnsignedShort4444Rev
+   | x == 0x8366 = UnsignedShort1555Rev
+   | x == 0x8367 = UnsignedInt8888Rev
+   | x == 0x8368 = UnsignedInt2101010Rev
+   | x == 0x85ba = UnsignedShort88
+   | x == 0x85bb = UnsignedShort88Rev
+   | x == 0x84fa = UnsignedInt248
+   | otherwise = error ("unmarshalDataType: illegal value " ++ show x)
diff --git a/Graphics/Rendering/OGL/GL/DisplayLists.hs b/Graphics/Rendering/OGL/GL/DisplayLists.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/DisplayLists.hs
@@ -0,0 +1,179 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.DisplayLists
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 5.4 (Display Lists) of the OpenGL 2.1
+-- specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.DisplayLists (
+   -- * Defining Display Lists
+   DisplayList(..), ListMode(..), defineList, defineNewList, listIndex,
+   listMode, maxListNesting,
+
+   -- * Calling Display Lists
+   callList, callLists, listBase,
+
+   -- * Deprecated Functions
+   genLists, deleteLists, isList,
+) where
+
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLboolean, GLuint, GLsizei, GLenum )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BufferObjects ( ObjectName(..) )
+import Graphics.Rendering.OGL.GL.DataType ( marshalDataType )
+import Graphics.Rendering.OGL.GL.VertexArrays ( DataType )
+import Graphics.Rendering.OGL.GL.Exception ( bracket_ )
+import Graphics.Rendering.OGL.GL.GLboolean ( unmarshalGLboolean )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetListIndex,GetListMode,GetMaxListNesting,GetListBase),
+   getEnum1, getSizei1 )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal ( recordOutOfMemory )
+
+--------------------------------------------------------------------------------
+
+newtype DisplayList = DisplayList GLuint
+   deriving ( Eq, Ord, Show )
+
+instance ObjectName DisplayList where
+   genObjectNames = liftIO . genLists_
+   deleteObjectNames = liftIO . deleteLists_
+   isObjectName = liftIO . isList_
+
+--------------------------------------------------------------------------------
+
+{-# DEPRECATED genLists "use `genObjectNames' instead" #-}
+genLists :: GLsizei -> GL [DisplayList]
+genLists = liftIO . genLists_ . fromIntegral
+
+genLists_ :: Int -> IO [DisplayList]
+genLists_ n = do
+   first <- glGenLists (fromIntegral n)
+   if DisplayList first == noDisplayList
+      then do recordOutOfMemory
+              return []
+      else return [ DisplayList l | l <- [ first .. first + fromIntegral n - 1 ] ]
+
+foreign import CALLCONV unsafe "glGenLists" glGenLists :: GLsizei -> IO GLuint
+
+--------------------------------------------------------------------------------
+
+{-# DEPRECATED deleteLists "use `deleteObjectNames' instead" #-}
+deleteLists :: [DisplayList] -> GL ()
+deleteLists = liftIO . deleteLists_
+
+deleteLists_ :: [DisplayList] -> IO ()
+deleteLists_ = mapM_ (uncurry glDeleteLists) . combineConsecutive
+
+foreign import CALLCONV unsafe "glDeleteLists" glDeleteLists ::
+   DisplayList -> GLsizei -> IO ()
+
+combineConsecutive :: [DisplayList] -> [(DisplayList, GLsizei)]
+combineConsecutive []     = []
+combineConsecutive (z:zs) = (z, len) : combineConsecutive rest
+   where (len, rest) = run (0 :: GLsizei) z zs
+         run n x xs = case n + 1 of
+                         m -> case xs of
+                                 []                          -> (m, [])
+                                 (y:ys) | x `isFollowedBy` y -> run m y ys
+                                        | otherwise          -> (m, xs)
+         DisplayList x `isFollowedBy` DisplayList y = x + 1 == y
+
+--------------------------------------------------------------------------------
+
+{-# DEPRECATED isList "use `isObjectName' instead" #-}
+isList :: DisplayList -> GL Bool
+isList = liftIO . isList_
+
+isList_ :: DisplayList -> IO Bool
+isList_ = fmap unmarshalGLboolean . glIsList
+
+foreign import CALLCONV unsafe "glIsList" glIsList ::
+   DisplayList -> IO GLboolean
+
+--------------------------------------------------------------------------------
+
+data ListMode =
+     Compile
+   | CompileAndExecute
+   deriving ( Eq, Ord, Show )
+
+marshalListMode :: ListMode -> GLenum
+marshalListMode x = case x of
+   Compile -> 0x1300
+   CompileAndExecute -> 0x1301
+
+unmarshalListMode :: GLenum -> ListMode
+unmarshalListMode x
+   | x == 0x1300 = Compile
+   | x == 0x1301 = CompileAndExecute
+   | otherwise = error ("unmarshalListMode: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+defineList :: DisplayList -> ListMode -> GL a -> GL a
+defineList lst mode f = liftIO $ bracket_ 
+									(glNewList lst $ marshalListMode mode) 
+									(glEndList)
+									(runGL f)
+									
+
+foreign import CALLCONV unsafe "glNewList" glNewList ::
+   DisplayList -> GLenum -> IO ()
+
+foreign import CALLCONV unsafe "glEndList" glEndList :: IO ()
+
+defineNewList :: ListMode -> GL a -> GL DisplayList
+defineNewList mode action = do
+   lists <- genLists 1
+   if null lists
+      then do liftIO $ recordOutOfMemory
+              return noDisplayList
+      else do let lst = head lists
+              defineList lst mode action
+              return lst
+
+--------------------------------------------------------------------------------
+
+listIndex :: GettableStateVar (Maybe DisplayList)
+listIndex =
+   makeGettableStateVar
+      (do l <- getEnum1 DisplayList GetListIndex
+          return $ if l == noDisplayList then Nothing else Just l)
+
+noDisplayList :: DisplayList
+noDisplayList = DisplayList 0
+
+listMode :: GettableStateVar ListMode
+listMode = makeGettableStateVar (getEnum1 unmarshalListMode GetListMode)
+
+maxListNesting :: GettableStateVar GLsizei
+maxListNesting = makeGettableStateVar (getSizei1 id GetMaxListNesting)
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glCallList" callList :: DisplayList -> GL ()
+
+callLists :: GLsizei -> DataType -> Ptr a -> GL ()
+callLists n = glCallLists n . marshalDataType
+
+foreign import CALLCONV unsafe "glCallLists" glCallLists ::
+   GLsizei -> GLenum -> Ptr a -> GL ()
+
+--------------------------------------------------------------------------------
+
+listBase :: StateVar DisplayList
+listBase = makeStateVar (getEnum1 DisplayList GetListBase) glListBase
+
+foreign import CALLCONV unsafe "glListBase" glListBase :: DisplayList -> IO ()
diff --git a/Graphics/Rendering/OGL/GL/Domain.hs b/Graphics/Rendering/OGL/GL/Domain.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Domain.hs
@@ -0,0 +1,139 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Domain
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for handling evaluator domains.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Domain (
+   Domain(..)
+) where
+
+import Foreign.Ptr ( Ptr )
+import Foreign.Storable ( Storable )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLenum, GLint, GLfloat, GLdouble )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName, getFloat2, getFloat4, getDouble2, getDouble4 )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLTypes.h"
+
+--------------------------------------------------------------------------------
+
+class Storable d => Domain d where
+   glMap1      :: GLenum -> d -> d -> GLint -> GLint -> Ptr d -> IO ()
+   glMap2      :: GLenum -> d -> d -> GLint -> GLint -> d -> d -> GLint -> GLint -> Ptr d -> IO ()
+   glGetMapv   :: GLenum -> GLenum -> Ptr d -> IO ()
+   evalCoord1  :: MonadGL m => d -> m ()
+   evalCoord1v :: MonadGL m => Ptr d -> m ()
+   evalCoord2  :: MonadGL m => (d, d) -> m ()
+   evalCoord2v :: MonadGL m => Ptr d -> m ()
+   glMapGrid1  :: GLint -> d -> d -> IO ()
+   glMapGrid2  :: GLint -> d -> d -> GLint -> d -> d -> IO ()
+   get2        :: (d -> d -> a) -> GetPName -> IO a
+   get4        :: (d -> d -> d -> d -> a) -> GetPName -> IO a
+
+--------------------------------------------------------------------------------
+
+instance Domain GLfloat_ where
+   glMap1      = glMap1f
+   glMap2      = glMap2f
+   glGetMapv   = glGetMapfv
+   evalCoord1  = liftIO . glEvalCoord1f
+   evalCoord1v = liftIO . glEvalCoord1fv
+   evalCoord2  = liftIO . uncurry glEvalCoord2f
+   evalCoord2v = liftIO . glEvalCoord2fv
+   glMapGrid1  = glMapGrid1f
+   glMapGrid2  = glMapGrid2f
+   get2        = getFloat2
+   get4        = getFloat4
+
+foreign import CALLCONV unsafe "glMap1f" glMap1f ::
+      GLenum
+   -> GLfloat -> GLfloat -> GLint -> GLint
+   -> Ptr GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glMap2f" glMap2f ::
+      GLenum
+   -> GLfloat -> GLfloat -> GLint -> GLint
+   -> GLfloat -> GLfloat -> GLint -> GLint
+   -> Ptr GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glGetMapfv" glGetMapfv ::
+   GLenum -> GLenum -> Ptr GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glEvalCoord1f" glEvalCoord1f ::
+   GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glEvalCoord1fv" glEvalCoord1fv ::
+   Ptr GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glEvalCoord2f" glEvalCoord2f ::
+   GLfloat -> GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glEvalCoord2fv" glEvalCoord2fv ::
+   Ptr GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glMapGrid1f" glMapGrid1f ::
+   GLint -> GLfloat -> GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glMapGrid2f" glMapGrid2f ::
+   GLint -> GLfloat -> GLfloat -> GLint -> GLfloat -> GLfloat -> IO ()
+
+--------------------------------------------------------------------------------
+
+instance Domain GLdouble_ where
+   glMap1      = glMap1d
+   glMap2      = glMap2d
+   glGetMapv   = glGetMapdv
+   evalCoord1  = liftIO . glEvalCoord1d
+   evalCoord1v = liftIO . glEvalCoord1dv
+   evalCoord2  = liftIO . uncurry glEvalCoord2d
+   evalCoord2v = liftIO . glEvalCoord2dv
+   glMapGrid1  = glMapGrid1d
+   glMapGrid2  = glMapGrid2d
+   get2        = getDouble2
+   get4        = getDouble4
+
+foreign import CALLCONV unsafe "glMap1d" glMap1d ::
+      GLenum
+   -> GLdouble -> GLdouble -> GLint -> GLint
+   -> Ptr GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glMap2d" glMap2d ::
+      GLenum
+   -> GLdouble -> GLdouble -> GLint -> GLint
+   -> GLdouble -> GLdouble -> GLint -> GLint
+   -> Ptr GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glGetMapdv" glGetMapdv ::
+   GLenum -> GLenum -> Ptr GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glEvalCoord1d" glEvalCoord1d ::
+   GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glEvalCoord1dv" glEvalCoord1dv ::
+   Ptr GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glEvalCoord2d" glEvalCoord2d ::
+   GLdouble -> GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glEvalCoord2dv" glEvalCoord2dv ::
+   Ptr GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glMapGrid1d" glMapGrid1d ::
+   GLint -> GLdouble -> GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glMapGrid2d" glMapGrid2d ::
+   GLint -> GLdouble -> GLdouble -> GLint -> GLdouble -> GLdouble -> IO ()
diff --git a/Graphics/Rendering/OGL/GL/EdgeFlag.hs b/Graphics/Rendering/OGL/GL/EdgeFlag.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/EdgeFlag.hs
@@ -0,0 +1,38 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.EdgeFlag
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for (un-)marshaling EdgeFlag.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.EdgeFlag (
+   EdgeFlag(..), marshalEdgeFlag, unmarshalEdgeFlag
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLboolean )
+import Graphics.Rendering.OGL.GL.GLboolean (
+   marshalGLboolean, unmarshalGLboolean )
+
+--------------------------------------------------------------------------------
+
+-- | A vertex can begin an edge which lies in the interior of its polygon or on
+-- the polygon\'s boundary.
+
+data EdgeFlag = BeginsInteriorEdge | BeginsBoundaryEdge
+   deriving ( Eq, Ord, Show )
+
+marshalEdgeFlag :: EdgeFlag -> GLboolean
+marshalEdgeFlag = marshalGLboolean . (BeginsBoundaryEdge ==)
+
+unmarshalEdgeFlag :: GLboolean -> EdgeFlag
+unmarshalEdgeFlag f =
+   if unmarshalGLboolean f then BeginsBoundaryEdge else BeginsBoundaryEdge
diff --git a/Graphics/Rendering/OGL/GL/Evaluators.hs b/Graphics/Rendering/OGL/GL/Evaluators.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Evaluators.hs
@@ -0,0 +1,408 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Evaluators
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 5.1 (Evaluators) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Evaluators (
+   -- * Evaluator-related Types
+   Order, maxOrder, Domain, MapDescriptor(..), ControlPoint,
+
+   -- * Defining Evaluator Maps
+   -- ** One-dimensional Evaluator Maps
+   Map1(..), GLmap1, map1,
+
+   -- ** Two-dimensional Evaluator Maps
+   Map2(..), GLmap2, map2,
+
+   -- * Using Evaluator Maps
+
+   -- ** Evaluating an Arbitrary Coordinate Value
+   evalCoord1, evalCoord1v, evalCoord2, evalCoord2v,
+
+   -- ** Using Evenly Spaced Coordinate Values
+
+   -- *** Defining a Grid
+   mapGrid1, mapGrid2,
+
+   -- *** Evaluating a Whole Mesh
+   evalMesh1, evalMesh2,
+
+   -- *** Evaluating a Single Point on a Mesh
+   evalPoint1, evalPoint2,
+
+   -- * Normal Generation
+   autoNormal
+) where
+
+import Control.Monad ( zipWithM_ )
+import Data.List ( genericLength )
+import Foreign.ForeignPtr ( ForeignPtr, mallocForeignPtrArray, withForeignPtr )
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Marshal.Array ( allocaArray )
+import Foreign.Ptr ( Ptr, plusPtr )
+import Foreign.Storable ( Storable(peek,sizeOf) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapAutoNormal), makeCapability, makeStateVarMaybe )
+import Graphics.Rendering.OGL.GL.ControlPoint
+import Graphics.Rendering.OGL.GL.Domain
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum, GLint, Capability )
+import Graphics.Rendering.OGL.GL.PeekPoke ( peek2, peek4 )
+import Graphics.Rendering.OGL.GL.PolygonMode ( marshalPolygonMode )
+import Graphics.Rendering.OGL.GL.Polygons ( PolygonMode )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetMaxEvalOrder,
+            GetMap1GridSegments,GetMap1GridDomain,
+            GetMap2GridSegments,GetMap2GridDomain),
+   getSizei1, getInteger1, getInteger2 )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.VertexArrays ( NumComponents, Stride )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLTypes.h"
+
+--------------------------------------------------------------------------------
+
+type Order = GLint
+
+maxOrder :: GettableStateVar Order
+maxOrder = makeGettableStateVar (getSizei1 id GetMaxEvalOrder)
+
+--------------------------------------------------------------------------------
+
+data Domain d => MapDescriptor d =
+   MapDescriptor (d, d) Stride Order NumComponents
+   deriving ( Eq, Ord, Show )
+
+totalComponents1 :: Domain d => MapDescriptor d -> Int
+totalComponents1 (MapDescriptor _ stride order numComp) =
+   fromIntegral stride * (fromIntegral order - 1) + fromIntegral numComp
+
+totalComponents2 :: Domain d => MapDescriptor d -> MapDescriptor d -> Int
+totalComponents2 uDescriptor vDescriptor@(MapDescriptor _ _ _ numComp) =
+   totalComponents1 uDescriptor + totalComponents1 vDescriptor - fromIntegral numComp
+
+--------------------------------------------------------------------------------
+
+peekControlPoints1 ::
+   (ControlPoint c, Domain d) => MapDescriptor d -> Ptr d -> IO [c d]
+peekControlPoints1 descriptor ptr =
+   mapM peekControlPoint (controlPointPtrs1 descriptor ptr)
+
+peekControlPoints2 ::
+      (ControlPoint c, Domain d)
+   => MapDescriptor d -> MapDescriptor d -> Ptr d -> IO [[c d]]
+peekControlPoints2 uDescriptor vDescriptor ptr =
+   mapM (mapM peekControlPoint) (controlPointPtrs2 uDescriptor vDescriptor ptr)
+
+pokeControlPoints1 ::
+   (ControlPoint c, Domain d) => MapDescriptor d -> Ptr d -> [c d] -> IO ()
+pokeControlPoints1 descriptor ptr =
+   zipWithM_ pokeControlPoint (controlPointPtrs1 descriptor ptr)
+
+pokeControlPoints2 ::
+      (ControlPoint c, Domain d)
+   => MapDescriptor d -> MapDescriptor d -> Ptr d -> [[c d]] -> IO ()
+pokeControlPoints2 uDescriptor vDescriptor ptr =
+   zipWithM_ (zipWithM_ pokeControlPoint)
+             (controlPointPtrs2 uDescriptor vDescriptor ptr)
+
+controlPointPtrs1 :: Domain d => MapDescriptor d -> Ptr d -> [Ptr a]
+controlPointPtrs1 (MapDescriptor _ stride order _) ptr =
+   [ ptr `plusPtr` (o * s) | o <- [ 0 .. fromIntegral order - 1 ] ]
+   where s = sizeOfPtr ptr * fromIntegral stride
+
+controlPointPtrs2 ::
+   Domain d => MapDescriptor d -> MapDescriptor d -> Ptr d -> [[Ptr a]]
+controlPointPtrs2 uDescriptor vDescriptor ptr =
+   [ controlPointPtrs1 vDescriptor p | p <- controlPointPtrs1 uDescriptor ptr ]
+
+sizeOfPtr :: Storable a => Ptr a -> Int
+sizeOfPtr = (flip (const sizeOf) :: Storable a => Ptr a -> a -> Int) undefined
+
+--------------------------------------------------------------------------------
+
+class Map1 m where
+   withNewMap1 :: (ControlPoint c, Domain d)
+      => MapDescriptor d -> (Ptr d -> GL ()) -> GL (m c d)
+
+   withMap1 :: (ControlPoint c, Domain d)
+      => m c d -> (MapDescriptor d -> Ptr d -> GL a) -> GL a
+
+   newMap1 :: (ControlPoint c, Domain d)
+      => (d, d) -> [c d] -> GL (m c d)
+
+   getMap1Components :: (ControlPoint c, Domain d)
+      => m c d -> GL ((d, d), [c d])
+
+   withNewMap1 descriptor@(MapDescriptor domain _ _ _) act = liftIO $ do
+      allocaArray (totalComponents1 descriptor) $ \ptr -> do
+         runGL $ act ptr
+         controlPoints <- peekControlPoints1 descriptor ptr
+         runGL $ newMap1 domain controlPoints
+
+   withMap1 m act = do
+      (domain, controlPoints) <- getMap1Components m
+	  
+      let stride = numComponents (head controlPoints)
+          order = genericLength controlPoints
+          descriptor = MapDescriptor domain stride order (fromIntegral stride)
+		  
+      liftIO . allocaArray (totalComponents1 descriptor) $ \ptr -> do
+         pokeControlPoints1 descriptor ptr controlPoints
+         runGL $ act descriptor ptr
+
+   newMap1 domain controlPoints = do
+      let stride = numComponents (head controlPoints)
+          order = genericLength controlPoints
+          descriptor = MapDescriptor domain stride order (fromIntegral stride)
+      withNewMap1 descriptor $ \ptr ->
+         liftIO $ pokeControlPoints1 descriptor ptr controlPoints
+
+   getMap1Components m =
+      withMap1 m $ \descriptor@(MapDescriptor domain _ _ _) ptr -> do
+         controlPoints <- liftIO $ peekControlPoints1 descriptor ptr
+         return (domain, controlPoints)
+
+--------------------------------------------------------------------------------
+
+data (ControlPoint c, Domain d) => GLmap1 c d =
+   GLmap1 (MapDescriptor d) (ForeignPtr d)
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq d => Eq (GLmap1 c d)
+instance Ord d => Ord (GLmap1 c d)
+instance Show d => Show (GLmap1 c d)
+#else
+   deriving ( Eq, Ord, Show )
+#endif
+
+instance Map1 GLmap1 where
+   withNewMap1 descriptor act = liftIO $ do
+      fp <- mallocForeignPtrArray (totalComponents1 descriptor)
+      withForeignPtr fp (runGL . act)
+      return $ GLmap1 descriptor fp
+
+   withMap1 (GLmap1 descriptor fp) act = liftIO $
+      withForeignPtr fp $ (runGL . act descriptor)
+
+--------------------------------------------------------------------------------
+ 
+map1 :: (Map1 m, ControlPoint c, Domain d) => StateVar (Maybe (m c d))
+map1 = makeMap1StateVar enableCap1 getMap1 setMap1
+
+makeMap1StateVar ::
+      (c d -> EnableCap) -> (c d -> IO (m c d)) -> (c d -> m c d -> IO ())
+   -> StateVar (Maybe (m c d))
+makeMap1StateVar getCap getAct setAct =
+   makeStateVarMaybe
+      (return (getCap undefined))
+      (getAct undefined)
+      (setAct undefined)
+
+getMap1 :: (Map1 m, ControlPoint c, Domain d) => c d -> IO (m c d)
+getMap1 dummyControlPoint = do
+   let target = map1Target dummyControlPoint
+       numComp = fromIntegral (numComponents dummyControlPoint)
+   domain <- allocaArray 2 $ \ptr -> do
+      glGetMapv target (marshalGetMapQuery Domain) ptr
+      peek2 (,) ptr
+   order <- alloca $ \ptr -> do
+      glGetMapiv target (marshalGetMapQuery Order) ptr
+      fmap fromIntegral $ peek ptr
+   runGL $ withNewMap1 (MapDescriptor domain (numComponents dummyControlPoint) order numComp) $
+      (liftIO . glGetMapv target (marshalGetMapQuery Coeff))
+
+setMap1 :: (Map1 m, ControlPoint c, Domain d) => c d -> m c d -> IO ()
+setMap1 dummyControlPoint m = runGL $
+   withMap1 m $ \(MapDescriptor (u1, u2) stride order _) -> liftIO . 
+      glMap1 (map1Target dummyControlPoint) u1 u2
+             (fromIntegral stride) (fromIntegral order)
+
+--------------------------------------------------------------------------------
+
+class Map2 m where
+   withNewMap2 :: (ControlPoint c, Domain d)
+      => MapDescriptor d -> MapDescriptor d -> (Ptr d -> GL ()) -> GL (m c d)
+
+   withMap2 :: (ControlPoint c, Domain d)
+      => m c d -> (MapDescriptor d -> MapDescriptor d -> Ptr d -> GL a) -> GL a
+
+   newMap2 :: (ControlPoint c, Domain d)
+      => (d, d) -> (d, d) -> [[c d]] -> GL (m c d)
+
+   getMap2Components :: (ControlPoint c, Domain d)
+      => m c d -> GL ((d, d), (d, d), [[c d]])
+
+   withNewMap2 uDescriptor@(MapDescriptor uDomain _ _ _)
+               vDescriptor@(MapDescriptor vDomain _ _ _) act = liftIO . 
+      allocaArray (totalComponents2 uDescriptor vDescriptor) $ \ptr -> do
+         runGL $ act ptr
+         controlPoints <- peekControlPoints2 uDescriptor vDescriptor ptr
+         runGL $ newMap2 uDomain vDomain controlPoints
+
+   withMap2 m act = do
+      (uDomain, vDomain, controlPoints) <- getMap2Components m
+      let vStride = numComponents (head (head controlPoints))
+          vOrder = genericLength (head controlPoints)
+          uStride = vStride * fromIntegral vOrder
+          uOrder = genericLength controlPoints
+          numComp = fromIntegral vStride
+          uDescriptor = MapDescriptor uDomain uStride uOrder numComp
+          vDescriptor = MapDescriptor vDomain vStride vOrder numComp
+      liftIO . allocaArray (totalComponents2 uDescriptor vDescriptor) $ \ptr -> do
+         pokeControlPoints2 uDescriptor vDescriptor ptr controlPoints
+         runGL $ act uDescriptor vDescriptor ptr
+
+   newMap2 uDomain vDomain controlPoints = do
+      let vStride = numComponents (head (head controlPoints))
+          vOrder = genericLength (head controlPoints)
+          uStride = vStride * fromIntegral vOrder
+          uOrder = genericLength controlPoints
+          numComp = fromIntegral vStride
+          uDescriptor = MapDescriptor uDomain uStride uOrder numComp
+          vDescriptor = MapDescriptor vDomain vStride vOrder numComp
+      withNewMap2 uDescriptor vDescriptor $ \ptr -> liftIO $ 
+         pokeControlPoints2 uDescriptor vDescriptor ptr controlPoints
+
+   getMap2Components m =
+      withMap2 m $ \uDescriptor@(MapDescriptor uDomain _ _ _)
+                    vDescriptor@(MapDescriptor vDomain _ _ _) ptr -> do
+         controlPoints <- liftIO $ peekControlPoints2 uDescriptor vDescriptor ptr
+         return (uDomain, vDomain, controlPoints)
+
+--------------------------------------------------------------------------------
+
+data (ControlPoint c, Domain d) => GLmap2 c d =
+   GLmap2 (MapDescriptor d)  (MapDescriptor d) (ForeignPtr d)
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq d => Eq (GLmap2 c d)
+instance Ord d => Ord (GLmap2 c d)
+instance Show d => Show (GLmap2 c d)
+#else
+   deriving ( Eq, Ord, Show )
+#endif
+
+instance Map2 GLmap2 where
+   withNewMap2 uDescriptor vDescriptor act = liftIO $ do
+      fp <- mallocForeignPtrArray (totalComponents2 uDescriptor vDescriptor)
+      withForeignPtr fp (runGL . act)
+      return $ GLmap2 uDescriptor vDescriptor fp
+
+   withMap2 (GLmap2 uDescriptor vDescriptor fp) act = liftIO . 
+      withForeignPtr fp $ (runGL . act uDescriptor vDescriptor)
+
+--------------------------------------------------------------------------------
+
+map2 :: (Map2 m, ControlPoint c, Domain d) => StateVar (Maybe (m c d))
+map2 = makeMap2StateVar enableCap2 getMap2 setMap2
+
+makeMap2StateVar ::
+      (c d -> EnableCap) -> (c d -> IO (m c d)) -> (c d -> m c d -> IO ())
+   -> StateVar (Maybe (m c d))
+makeMap2StateVar getCap getAct setAct =
+   makeStateVarMaybe
+      (return (getCap undefined))
+      (getAct undefined)
+      (setAct undefined)
+
+getMap2 :: (Map2 m, ControlPoint c, Domain d) => c d -> IO (m c d)
+getMap2 dummyControlPoint = do
+   let target = map2Target dummyControlPoint
+   (uDomain, vDomain) <- allocaArray 4 $ \ptr -> do
+      glGetMapv target (marshalGetMapQuery Domain) ptr
+      peek4 (\u1 u2 v1 v2 -> ((u1, u2), (v1, v2))) ptr
+   (uOrder, vOrder) <- allocaArray 2 $ \ptr -> do
+      glGetMapiv target (marshalGetMapQuery Order) ptr
+      peek2 (,) ptr
+   let vStride = numComponents dummyControlPoint
+       uStride = vStride * fromIntegral vOrder
+   runGL . withNewMap2 (MapDescriptor uDomain uStride uOrder (fromIntegral vStride))
+               (MapDescriptor vDomain vStride vOrder (fromIntegral vStride)) $
+      (liftIO . glGetMapv target (marshalGetMapQuery Coeff))
+
+setMap2 :: (Map2 m, ControlPoint c, Domain d) => c d -> m c d -> IO ()
+setMap2 dummyControlPoint m = runGL . 
+   withMap2 m $ \(MapDescriptor (u1, u2) uStride uOrder _)
+                 (MapDescriptor (v1, v2) vStride vOrder _) ->
+      liftIO . glMap2 (map2Target dummyControlPoint)
+             u1 u2 (fromIntegral uStride) (fromIntegral uOrder)
+             v1 v2 (fromIntegral vStride) (fromIntegral vOrder)
+
+--------------------------------------------------------------------------------
+
+data GetMapQuery =
+     Coeff
+   | Order
+   | Domain
+
+marshalGetMapQuery :: GetMapQuery -> GLenum
+marshalGetMapQuery x = case x of
+   Coeff -> 0xa00
+   Order -> 0xa01
+   Domain -> 0xa02
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glGetMapiv" glGetMapiv ::
+   GLenum -> GLenum -> Ptr GLint -> IO ()
+
+--------------------------------------------------------------------------------
+
+mapGrid1 :: Domain d => StateVar (GLint, (d, d))
+mapGrid1 =
+   makeStateVar
+      (do n <- getInteger1 id GetMap1GridSegments
+          domain <- get2 (,) GetMap1GridDomain
+          return (n, domain))
+      (\(n, (u1, u2)) -> glMapGrid1 n u1 u2)
+
+mapGrid2 :: Domain d => StateVar ((GLint, (d, d)), (GLint, (d, d)))
+mapGrid2 =
+   makeStateVar
+      (do (un, vn) <- getInteger2 (,) GetMap2GridSegments
+          (u1, u2, v1, v2) <- get4 (,,,) GetMap2GridDomain
+          return ((un, (u1, u2)), (vn, (v1, v2))))
+      (\((un, (u1, u2)), (vn, (v1, v2))) -> glMapGrid2 un u1 u2 vn v1 v2)
+
+--------------------------------------------------------------------------------
+
+evalMesh1 :: PolygonMode -> (GLint, GLint) -> GL ()
+evalMesh1 m (p1, p2) = glEvalMesh1 (marshalPolygonMode m) p1 p2
+
+foreign import CALLCONV unsafe "glEvalMesh1" glEvalMesh1 ::
+   GLenum -> GLint -> GLint -> GL ()
+
+evalMesh2 :: PolygonMode -> (GLint, GLint) -> (GLint, GLint) -> GL ()
+evalMesh2 m (p1, p2) (q1, q2) = glEvalMesh2 (marshalPolygonMode m) p1 p2 q1 q2
+
+foreign import CALLCONV unsafe "glEvalMesh2" glEvalMesh2 ::
+   GLenum -> GLint -> GLint -> GLint -> GLint -> GL ()
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glEvalPoint1" evalPoint1 ::
+   GLint -> PrimitiveGL ()
+
+evalPoint2 :: (GLint, GLint) -> PrimitiveGL ()
+evalPoint2 = uncurry glEvalPoint2
+
+foreign import CALLCONV unsafe "glEvalPoint2" glEvalPoint2 ::
+   GLint -> GLint -> PrimitiveGL ()
+
+--------------------------------------------------------------------------------
+
+autoNormal :: StateVar Capability
+autoNormal = makeCapability CapAutoNormal
diff --git a/Graphics/Rendering/OGL/GL/Exception.hs b/Graphics/Rendering/OGL/GL/Exception.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Exception.hs
@@ -0,0 +1,55 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Exception
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module to compensate for differences between
+-- Haskell implementations.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Exception (
+   bracket, bracket_, unsafeBracket_, finallyRet
+) where
+
+import Data.IORef ( newIORef, readIORef, writeIORef )
+
+import Graphics.Rendering.OGL.Monad
+#ifdef __NHC__
+import qualified IO ( bracket, bracket_ )
+
+{-# INLINE bracket #-}
+bracket  :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
+bracket = IO.bracket
+
+{-# INLINE bracket_ #-}
+bracket_ :: IO a -> IO b -> IO c -> IO c
+bracket_ before = IO.bracket_ before . const
+
+finally :: IO a -> IO b -> IO a
+finally = flip . bracket_ . return $ undefined
+#else
+import Control.Exception ( bracket, bracket_, finally )
+#endif
+
+{-# INLINE unsafeBracket_ #-}
+unsafeBracket_ :: IO a -> IO b -> IO c -> IO c
+unsafeBracket_ before after thing = do
+   before
+   r <- thing
+   after
+   return r
+
+{-# INLINE finallyRet #-}
+finallyRet :: IO a -> IO b -> IO (a, b)
+a `finallyRet` sequel = do
+   r2Ref <- newIORef undefined
+   r1 <- a `finally` (sequel >>= writeIORef r2Ref)
+   r2 <- readIORef r2Ref
+   return (r1, r2)
diff --git a/Graphics/Rendering/OGL/GL/Extensions.hs b/Graphics/Rendering/OGL/GL/Extensions.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Extensions.hs
@@ -0,0 +1,48 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Extensions
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for handling the OpenGL extension
+-- mechanism.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO,
+   Invoker, getProcAddress   -- used only internally
+) where
+
+import Foreign.C.String ( CString, withCString )
+import Foreign.Ptr ( FunPtr, nullFunPtr )
+import System.IO.Unsafe ( unsafePerformIO )
+
+import Graphics.Rendering.OGL.Monad
+#ifdef __HUGS__
+{-# CFILES cbits/HsOpenGL.c #-}
+#endif
+
+--------------------------------------------------------------------------------
+
+type Invoker a = FunPtr a -> a
+
+getProcAddress :: String -> String -> IO (FunPtr a)
+getProcAddress ext call =
+   throwIfNull ("unknown OpenGL call " ++ call ++ ", check for " ++ ext) $
+      withCString call hs_OpenGL_getProcAddress
+
+throwIfNull :: String -> IO (FunPtr a) -> IO (FunPtr a)
+throwIfNull msg act = do
+   res <- act
+   if res == nullFunPtr
+      then ioError (userError msg)
+      else return res
+
+foreign import ccall unsafe "hs_OpenGL_getProcAddress" hs_OpenGL_getProcAddress
+   :: CString -> IO (FunPtr a)
diff --git a/Graphics/Rendering/OGL/GL/Face.hs b/Graphics/Rendering/OGL/GL/Face.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Face.hs
@@ -0,0 +1,41 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Face
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for (un-)marshaling Face.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Face (
+   Face(..), marshalFace, unmarshalFace
+) where
+
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum )
+
+--------------------------------------------------------------------------------
+
+data Face =
+     Front
+   | Back
+   | FrontAndBack
+   deriving ( Eq, Ord, Show )
+
+marshalFace :: Face -> GLenum
+marshalFace x = case x of
+   Front -> 0x404
+   Back -> 0x405
+   FrontAndBack -> 0x408
+
+unmarshalFace :: GLenum -> Face
+unmarshalFace x
+   | x == 0x404 = Front
+   | x == 0x405 = Back
+   | x == 0x408 = FrontAndBack
+   | otherwise = error ("unmarshalFace: illegal value " ++ show x)
diff --git a/Graphics/Rendering/OGL/GL/Feedback.hs b/Graphics/Rendering/OGL/GL/Feedback.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Feedback.hs
@@ -0,0 +1,204 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Feedback
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 5.3 (Feedback) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Feedback (
+   FeedbackToken(..), VertexInfo(..), ColorInfo, FeedbackType(..),
+   getFeedbackTokens, PassThroughValue(..), passThrough
+) where
+
+import Control.Monad ( liftM2, liftM3, liftM4 )
+import Foreign.Marshal.Array ( allocaArray )
+import Foreign.Ptr ( Ptr, plusPtr )
+import Foreign.Storable ( Storable(sizeOf) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLenum, GLint, GLsizei, GLfloat )
+import Graphics.Rendering.OGL.GL.IOState (
+   IOState, getIOState, peekIOState, evalIOState, nTimes )
+import Graphics.Rendering.OGL.GL.RenderMode ( withRenderMode )
+import Graphics.Rendering.OGL.GL.Selection ( RenderMode(Feedback) )
+import Graphics.Rendering.OGL.GL.StateVar ( getIO )
+import Graphics.Rendering.OGL.GL.VertexSpec (
+   Vertex2(..), Vertex3(..), Vertex4(..), Index1(..), Color4(..),
+   TexCoord4(..), rgbaMode )
+
+--------------------------------------------------------------------------------
+
+data FeedbackToken =
+     PointToken VertexInfo
+   | LineToken VertexInfo VertexInfo
+   | LineResetToken VertexInfo VertexInfo
+   | PolygonToken [VertexInfo]
+   | BitmapToken VertexInfo
+   | DrawPixelToken VertexInfo
+   | CopyPixelToken VertexInfo
+   | PassThroughToken PassThroughValue
+   deriving ( Eq, Ord, Show )
+
+data VertexInfo =
+     Vertex2D             (Vertex2 GLfloat)
+   | Vertex3D             (Vertex3 GLfloat)
+   | Vertex3DColor        (Vertex3 GLfloat) ColorInfo
+   | Vertex3DColorTexture (Vertex3 GLfloat) ColorInfo (TexCoord4 GLfloat)
+   | Vertex4DColorTexture (Vertex4 GLfloat) ColorInfo (TexCoord4 GLfloat)
+   deriving ( Eq, Ord, Show )
+
+type ColorInfo = Either (Index1 GLint) (Color4 GLfloat)
+
+--------------------------------------------------------------------------------
+
+data FeedbackTag =
+     PointTag
+   | LineTag
+   | LineResetTag
+   | PolygonTag
+   | BitmapTag
+   | DrawPixelTag
+   | CopyPixelTag
+   | PassThroughTag
+
+unmarshalFeedbackTag :: GLenum -> FeedbackTag
+unmarshalFeedbackTag x
+   | x == 0x701 = PointTag
+   | x == 0x702 = LineTag
+   | x == 0x707 = LineResetTag
+   | x == 0x703 = PolygonTag
+   | x == 0x704 = BitmapTag
+   | x == 0x705 = DrawPixelTag
+   | x == 0x706 = CopyPixelTag
+   | x == 0x700 = PassThroughTag
+   | otherwise = error ("unmarshalFeedbackTag: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+data FeedbackType =
+     TwoD
+   | ThreeD
+   | ThreeDColor
+   | ThreeDColorTexture
+   | FourDColorTexture
+   deriving ( Eq, Ord, Show )
+
+marshalFeedbackType :: FeedbackType -> GLenum
+marshalFeedbackType x = case x of
+   TwoD -> 0x600
+   ThreeD -> 0x601
+   ThreeDColor -> 0x602
+   ThreeDColorTexture -> 0x603
+   FourDColorTexture -> 0x604
+
+--------------------------------------------------------------------------------
+
+getFeedbackTokens ::
+   GLsizei -> FeedbackType -> GL a -> GL (a, Maybe [FeedbackToken])
+getFeedbackTokens bufSize feedbackType action = liftIO .
+   allocaArray (fromIntegral bufSize) $ \buf -> do
+      glFeedbackBuffer bufSize (marshalFeedbackType feedbackType) buf
+      (value, numValues) <- withRenderMode Feedback (runGL action)
+      tokens <- parseFeedbackBuffer numValues buf feedbackType
+      return (value, tokens)
+
+foreign import CALLCONV unsafe "glFeedbackBuffer" glFeedbackBuffer ::
+   GLsizei -> GLenum -> Ptr GLfloat -> IO ()
+
+--------------------------------------------------------------------------------
+
+parseFeedbackBuffer ::
+   GLint -> Ptr GLfloat -> FeedbackType -> IO (Maybe [FeedbackToken])
+parseFeedbackBuffer numValues buf feedbackType
+   | numValues < 0 = return Nothing
+   | otherwise     = do
+      rgba <- getIO rgbaMode
+      let end = buf `plusPtr`
+                  (sizeOf (undefined :: GLfloat) * fromIntegral numValues)
+          infoParser = calcInfoParser feedbackType (calcColorParser rgba)
+          loop tokens = do
+             ptr <- getIOState
+             if ptr == end
+                then return (reverse tokens)
+                else do token <- tokenParser infoParser
+                        loop (token : tokens)
+      fmap Just $ evalIOState (loop []) buf
+
+type Parser a = IOState GLfloat a
+
+tokenParser :: Parser VertexInfo -> Parser FeedbackToken
+tokenParser infoParser = do
+   tag <- parseGLenum
+   case unmarshalFeedbackTag tag of
+      PointTag -> fmap PointToken infoParser
+      LineTag -> liftM2 LineToken infoParser infoParser
+      LineResetTag -> liftM2 LineResetToken infoParser infoParser
+      PolygonTag -> do n <- parseGLint; fmap PolygonToken (nTimes n infoParser)
+      BitmapTag -> fmap BitmapToken infoParser
+      DrawPixelTag -> fmap DrawPixelToken infoParser
+      CopyPixelTag -> fmap CopyPixelToken infoParser
+      PassThroughTag -> fmap PassThroughToken parsePassThroughValue
+
+calcInfoParser :: FeedbackType -> Parser ColorInfo -> Parser VertexInfo
+calcInfoParser feedbackType colorParser = case feedbackType of
+   TwoD ->
+      fmap Vertex2D parseVertex2
+   ThreeD ->
+      fmap Vertex3D parseVertex3
+   ThreeDColor ->
+      liftM2 Vertex3DColor parseVertex3 colorParser
+   ThreeDColorTexture ->
+      liftM3 Vertex3DColorTexture parseVertex3 colorParser parseTexCoord4
+   FourDColorTexture ->
+      liftM3 Vertex4DColorTexture parseVertex4 colorParser parseTexCoord4
+
+parseVertex2 :: Parser (Vertex2 GLfloat)
+parseVertex2 = liftM2 Vertex2 parseGLfloat parseGLfloat
+
+parseVertex3 :: Parser (Vertex3 GLfloat)
+parseVertex3 = liftM3 Vertex3 parseGLfloat parseGLfloat parseGLfloat
+
+parseVertex4 :: Parser (Vertex4 GLfloat)
+parseVertex4 =
+   liftM4 Vertex4 parseGLfloat parseGLfloat parseGLfloat parseGLfloat
+
+calcColorParser :: Bool -> Parser ColorInfo
+calcColorParser False = fmap Left parseIndex1
+calcColorParser True  = fmap Right parseColor4
+
+parseIndex1 :: Parser (Index1 GLint)
+parseIndex1 = fmap Index1 parseGLint
+
+parseColor4 :: Parser (Color4 GLfloat)
+parseColor4 = liftM4 Color4 parseGLfloat parseGLfloat parseGLfloat parseGLfloat
+
+parseTexCoord4 :: Parser (TexCoord4 GLfloat)
+parseTexCoord4 =
+   liftM4 TexCoord4 parseGLfloat parseGLfloat parseGLfloat parseGLfloat
+
+parsePassThroughValue :: Parser PassThroughValue
+parsePassThroughValue = fmap PassThroughValue parseGLfloat
+
+parseGLenum :: Parser GLenum
+parseGLenum = fmap round parseGLfloat
+
+parseGLint :: Parser GLint
+parseGLint = fmap round parseGLfloat
+
+parseGLfloat :: Parser GLfloat
+parseGLfloat = peekIOState
+
+--------------------------------------------------------------------------------
+
+newtype PassThroughValue = PassThroughValue GLfloat
+   deriving ( Eq, Ord, Show )
+
+foreign import CALLCONV unsafe "glPassThrough" passThrough ::
+   PassThroughValue -> GL ()
diff --git a/Graphics/Rendering/OGL/GL/FlushFinish.hs b/Graphics/Rendering/OGL/GL/FlushFinish.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/FlushFinish.hs
@@ -0,0 +1,47 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.FlushFinish
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 5.5 (Flush and Finish) of the OpenGL 2.1
+-- specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.FlushFinish (
+   flush, finish      
+) where
+
+import Graphics.Rendering.OGL.Monad
+--------------------------------------------------------------------------------
+
+-- | Different GL implementations buffer commands in several different
+-- locations, including network buffers and the graphics accelerator itself.
+-- 'flush' empties all of these buffers, causing all issued commands to be
+-- executed as quickly as they are accepted by the actual rendering engine.
+-- Though this execution may not be completed in any particular time period, it
+-- does complete in finite time.
+-- 
+-- Because any GL program might be executed over a network, or on an accelerator
+-- that buffers commands, all programs should call 'flush' whenever they count
+-- on having all of their previously issued commands completed. For example,
+-- call 'flush' before waiting for user input that depends on the generated
+-- image.
+-- 
+-- Note that 'flush' can return at any time. It does not wait until the
+-- execution of all previously issued GL commands is complete.
+
+foreign import CALLCONV unsafe "glFlush" flush :: GL ()
+
+-- | 'finish' does not return until the effects of all previously called GL
+-- commands are complete. Such effects include all changes to GL state, all
+-- changes to connection state, and all changes to the frame buffer contents.
+-- 
+-- Note that 'finish' requires a round trip to the server.
+
+foreign import CALLCONV unsafe "glFinish" finish :: GL ()
diff --git a/Graphics/Rendering/OGL/GL/Fog.hs b/Graphics/Rendering/OGL/GL/Fog.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Fog.hs
@@ -0,0 +1,207 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Fog
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.10 (Fog) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Fog (
+   fog,
+   FogMode(..), fogMode,
+   fogColor, fogIndex,
+   FogCoordSrc(..), fogCoordSrc,
+   FogDistanceMode(..), fogDistanceMode
+) where
+
+import Foreign.Marshal.Utils ( with )
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapFog), makeCapability )
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLenum, GLint, GLfloat, Capability )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetFogIndex,GetFogDensity,GetFogStart,GetFogEnd,GetFogMode,
+   GetFogColor,GetFogCoordSrc,GetFogDistanceMode),
+   getInteger1, getFloat1, getFloat4 )
+import Graphics.Rendering.OGL.GL.StateVar ( StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.VertexSpec (
+   Color4(Color4), Index1(Index1) )
+
+--------------------------------------------------------------------------------
+
+fog :: StateVar Capability
+fog = makeCapability CapFog
+
+--------------------------------------------------------------------------------
+
+data FogParameter =
+     FogIndex
+   | FogDensity
+   | FogStart
+   | FogEnd
+   | FogMode
+   | FogColor
+   | FogCoordSrc
+   | FogDistanceMode
+
+marshalFogParameter :: FogParameter -> GLenum
+marshalFogParameter x = case x of
+   FogIndex -> 0xb61
+   FogDensity -> 0xb62
+   FogStart -> 0xb63
+   FogEnd -> 0xb64
+   FogMode -> 0xb65
+   FogColor -> 0xb66
+   FogCoordSrc -> 0x8450
+   FogDistanceMode -> 0x855a
+
+--------------------------------------------------------------------------------
+
+data FogMode' =
+     Linear'
+   | Exp'
+   | Exp2'
+
+marshalFogMode' :: FogMode' -> GLint
+marshalFogMode' x = case x of
+   Linear' -> 0x2601
+   Exp' -> 0x800
+   Exp2' -> 0x801
+
+unmarshalFogMode' :: GLint -> FogMode'
+unmarshalFogMode' x
+   | x == 0x2601 = Linear'
+   | x == 0x800 = Exp'
+   | x == 0x801 = Exp2'
+   | otherwise = error ("unmarshalFogMode': illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+data FogMode =
+     Linear GLfloat GLfloat
+   | Exp GLfloat
+   | Exp2 GLfloat
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+fogMode :: StateVar FogMode
+fogMode = makeStateVar getFogMode setFogMode
+
+getFogMode :: IO FogMode
+getFogMode = do
+   mode <- getInteger1 unmarshalFogMode' GetFogMode
+   case mode of
+      Linear' -> do
+         start <- getFloat1 id GetFogStart
+         end <- getFloat1 id GetFogEnd
+         return $ Linear start end
+      Exp' -> getFloat1 Exp GetFogDensity
+      Exp2' -> getFloat1 Exp2 GetFogDensity
+
+setFogMode :: FogMode -> IO ()
+setFogMode (Linear start end) = do
+   fogi FogMode (marshalFogMode' Linear')
+   fogf FogStart start
+   fogf FogEnd end
+setFogMode (Exp density) = do
+   fogi FogMode (marshalFogMode' Exp')
+   fogf FogDensity density
+setFogMode (Exp2 density) = do
+   fogi FogMode (marshalFogMode' Exp2')
+   fogf FogDensity density
+
+--------------------------------------------------------------------------------
+
+fogi :: FogParameter -> GLint -> IO ()
+fogi = glFogi . marshalFogParameter
+
+foreign import CALLCONV unsafe "glFogi" glFogi :: GLenum -> GLint -> IO ()
+
+fogf :: FogParameter -> GLfloat -> IO ()
+fogf = glFogf . marshalFogParameter
+
+foreign import CALLCONV unsafe "glFogf" glFogf :: GLenum -> GLfloat -> IO ()
+
+fogfv :: FogParameter -> Ptr (Color4 GLfloat) -> IO ()
+fogfv = glFogfv . marshalFogParameter
+
+foreign import CALLCONV unsafe "glFogfv" glFogfv ::
+   GLenum -> Ptr (Color4 GLfloat) -> IO ()
+
+--------------------------------------------------------------------------------
+
+fogColor :: StateVar (Color4 GLfloat)
+fogColor =
+   makeStateVar (getFloat4 Color4 GetFogColor) (\c -> with c $ fogfv FogColor)
+
+--------------------------------------------------------------------------------
+
+fogIndex :: StateVar (Index1 GLint)
+fogIndex =
+   makeStateVar
+      (getInteger1 Index1 GetFogIndex)
+      (\(Index1 i) -> fogi FogIndex i)
+
+--------------------------------------------------------------------------------
+
+data FogCoordSrc =
+     FogCoord
+   | FragmentDepth
+   deriving ( Eq, Ord, Show )
+
+marshalFogCoordSrc :: FogCoordSrc -> GLint
+marshalFogCoordSrc x = case x of
+   FogCoord -> 0x8451
+   FragmentDepth -> 0x8452
+
+unmarshalFogCoordSrc :: GLint -> FogCoordSrc
+unmarshalFogCoordSrc x
+   | x == 0x8451 = FogCoord
+   | x == 0x8452 = FragmentDepth
+   | otherwise = error ("unmarshalFogCoordSrc: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+fogCoordSrc :: StateVar FogCoordSrc
+fogCoordSrc =
+   makeStateVar
+      (getInteger1 unmarshalFogCoordSrc GetFogCoordSrc)
+      (fogi FogCoordSrc . marshalFogCoordSrc)
+
+--------------------------------------------------------------------------------
+
+data FogDistanceMode =
+     EyeRadial
+   | EyePlaneSigned
+   | EyePlaneAbsolute
+   deriving ( Eq, Ord, Show )
+
+marshalFogDistanceMode :: FogDistanceMode -> GLint
+marshalFogDistanceMode x = case x of
+   EyeRadial -> 0x855b
+   EyePlaneSigned -> 0x2502
+   EyePlaneAbsolute -> 0x855c
+
+unmarshalFogDistanceMode :: GLint -> FogDistanceMode
+unmarshalFogDistanceMode x
+   | x== 0x855b = EyeRadial
+   | x == 0x2502 = EyePlaneSigned
+   | x == 0x855c = EyePlaneAbsolute
+   | otherwise = error ("unmarshalFogDistanceMode: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+fogDistanceMode :: StateVar FogDistanceMode
+fogDistanceMode =
+   makeStateVar
+      (getInteger1 unmarshalFogDistanceMode GetFogDistanceMode)
+      (fogi FogDistanceMode . marshalFogDistanceMode)
diff --git a/Graphics/Rendering/OGL/GL/Framebuffer.hs b/Graphics/Rendering/OGL/GL/Framebuffer.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Framebuffer.hs
@@ -0,0 +1,461 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Framebuffer
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 4.2 (Whole Framebuffer Operations) of the
+-- OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Framebuffer (
+   -- * Querying the Buffer Configuration
+   auxBuffers, doubleBuffer, stereoBuffer,
+   rgbaBits, stencilBits, depthBits, accumBits,
+
+   -- * Selecting a Buffer for Writing
+   BufferMode(..), drawBuffer, drawBuffers, maxDrawBuffers,
+
+   -- * Fine Control of Buffer Updates
+   indexMask, colorMask, stencilMask, stencilMaskSeparate, depthMask,
+
+   -- * Clearing the Buffers
+   ClearBuffer(..), clear,
+   clearColor, clearIndex, clearStencil, clearDepth, clearAccum,
+
+   -- * The Accumulation Buffer
+   AccumOp(..), accum
+) where
+
+import Control.Monad ( liftM4 )
+import Data.List ( genericLength )
+import Data.Maybe ( isJust, fromJust )
+import Foreign.Marshal.Array ( withArray )
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BufferMode (
+   BufferMode(..), marshalBufferMode, unmarshalBufferMode )
+import Graphics.Rendering.OGL.GL.Capability (
+   marshalCapability, unmarshalCapability )
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLboolean, GLenum, GLsizei, GLint, GLuint, GLbitfield, GLfloat, GLclampf,
+   GLclampd,
+#ifdef __HADDOCK__
+   Capability(..)
+#else
+   Capability
+#endif
+   )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.Face ( Face, marshalFace )
+import Graphics.Rendering.OGL.GL.GLboolean ( unmarshalGLboolean )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetAuxBuffers,GetDoublebuffer,GetStereo,GetRedBits,GetGreenBits,
+            GetBlueBits,GetAlphaBits,GetStencilBits,GetDepthBits,
+            GetAccumRedBits,GetAccumGreenBits,GetAccumBlueBits,
+            GetAccumAlphaBits,GetDrawBuffer,GetIndexWritemask,GetColorWritemask,
+            GetDepthWritemask,GetStencilWritemask,GetColorClearValue,
+            GetIndexClearValue,GetDepthClearValue,GetStencilClearValue,
+            GetAccumClearValue,GetMaxDrawBuffers,GetDrawBufferN),
+   getInteger1, getBoolean1, getBoolean4, getEnum1, getSizei1, getFloat1,
+   getFloat4, getDouble1 )
+import Graphics.Rendering.OGL.GL.StateVar (
+   getIO, GettableStateVar, makeGettableStateVar,
+   SettableStateVar, makeSettableStateVar,
+   StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.VertexSpec (
+   Color4(Color4), Index1(Index1) )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal ( recordInvalidValue )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+
+--------------------------------------------------------------------------------
+
+-- | The implementation and context dependent number of auxiliary buffers.
+
+auxBuffers :: GettableStateVar GLsizei
+auxBuffers = makeGettableStateVar $ getSizei1 id GetAuxBuffers
+
+-- | 'True' if front and back buffers exist.
+
+doubleBuffer :: GettableStateVar Bool
+doubleBuffer =
+   makeGettableStateVar $ getBoolean1 unmarshalGLboolean GetDoublebuffer
+
+-- | 'True' if left and right buffers exist.
+
+stereoBuffer :: GettableStateVar Bool
+stereoBuffer =
+    makeGettableStateVar $ getBoolean1 unmarshalGLboolean GetStereo
+
+rgbaBits :: GettableStateVar (Color4 GLsizei)
+rgbaBits =
+   makeGettableStateVar $
+      liftM4 Color4 (getSizei1 id GetRedBits)
+                    (getSizei1 id GetGreenBits)
+                    (getSizei1 id GetBlueBits)
+                    (getSizei1 id GetAlphaBits)
+
+stencilBits :: GettableStateVar GLsizei
+stencilBits = makeGettableStateVar $ getSizei1 id GetStencilBits
+
+depthBits :: GettableStateVar GLsizei
+depthBits = makeGettableStateVar $ getSizei1 id GetDepthBits
+
+accumBits :: GettableStateVar (Color4 GLsizei)
+accumBits =
+   makeGettableStateVar $
+      liftM4 Color4 (getSizei1 id GetAccumRedBits)
+                    (getSizei1 id GetAccumGreenBits)
+                    (getSizei1 id GetAccumBlueBits)
+                    (getSizei1 id GetAccumAlphaBits)
+
+--------------------------------------------------------------------------------
+
+-- | When colors are written to the framebuffer, they are written into the color
+-- buffers specified by 'drawBuffer'.
+-- 
+-- If more than one color buffer is selected for drawing, then blending or
+-- logical operations are computed and applied independently for each color
+-- buffer and can produce different results in each buffer.
+--
+-- Monoscopic contexts include only left buffers, and stereoscopic contexts
+-- include both left and right buffers. Likewise, single-buffered contexts
+-- include only front buffers, and double-buffered contexts include both front
+-- and back buffers. The context is selected at GL initialization.
+--
+-- The initial value is 'FrontBuffers' for single-buffered contexts, and
+-- 'BackBuffers' for double-buffered contexts.
+
+drawBuffer :: StateVar BufferMode
+drawBuffer =
+   makeStateVar
+      (getEnum1 unmarshalBufferMode GetDrawBuffer)
+      (maybe recordInvalidValue glDrawBuffer . marshalBufferMode)
+
+foreign import CALLCONV unsafe "glDrawBuffer" glDrawBuffer ::
+   GLenum -> IO ()
+
+--------------------------------------------------------------------------------
+
+-- | 'drawBuffers' defines the draw buffers to which all fragment colors are
+-- written. The draw buffers being defined correspond in order to the respective
+-- fragment colors. The draw buffer for fragment colors beyond those specified
+-- is set to 'NoBuffers'.
+--
+-- Except for 'NoBuffers', a buffer may not appear more then once in the given
+-- list. Specifying a buffer more then once will result in an
+-- 'Graphics.Rendering.OGL.GLU.Errors.InvalidOperation'.
+--
+-- If fixed-function fragment shading is being performed, 'drawBuffers'
+-- specifies a set of draw buffers into which the fragment color is written.
+--
+-- If a fragment shader writes to @gl_FragColor@, 'drawBuffers' specifies a set
+-- of draw buffers into which the single fragment color defined by
+-- @gl_FragColor@ is written. If a fragment shader writes to @gl_FragData@,
+-- 'drawBuffers' specifies a set of draw buffers into which each of the multiple
+-- fragment colors defined by @gl_FragData@ are separately written. If a
+-- fragment shader writes to neither @gl_FragColor@ nor @gl_FragData@, the
+-- values of the fragment colors following shader execution are undefined, and
+-- may differ for each fragment color.
+
+drawBuffers :: StateVar [BufferMode]
+drawBuffers = makeStateVar getDrawBuffers setDrawBuffers
+
+getDrawBuffers :: IO [BufferMode]
+getDrawBuffers = do
+   n <- getIO maxDrawBuffers
+   mapM (getEnum1 unmarshalBufferMode . GetDrawBufferN) [ 0 .. n ]
+
+setDrawBuffers :: [BufferMode] -> IO ()
+setDrawBuffers modes = do
+   let ms = map marshalBufferMode modes
+   if all isJust ms
+      then withArray (map fromJust ms) $
+              glDrawBuffers (genericLength ms)
+      else recordInvalidValue
+
+EXTENSION_ENTRY("GL_ARB_draw_buffers or OpenGL 2.0",glDrawBuffers,GLsizei -> Ptr GLenum -> IO ())
+
+--------------------------------------------------------------------------------
+
+-- | Contains the maximum number of buffers that can activated via 'drawBuffers'
+-- or which can be simultaneously written into from within a fragment shader
+-- using the special output variable array @gl_FragData@. This constant
+-- effectively defines the size of the @gl_FragData@ array. The minimum legal
+-- value is 1.
+
+maxDrawBuffers :: GettableStateVar GLsizei
+maxDrawBuffers = makeGettableStateVar $ getSizei1 id GetMaxDrawBuffers
+
+--------------------------------------------------------------------------------
+
+-- | Controls the writing of individual bits in the color index buffers. The
+-- least significant /n/ bits of its value, where /n/ is the number of bits in a
+-- color index buffer, specify a mask.  Where a 1 appears in the mask, it is
+-- possible to write to the corresponding bit in the color index buffer (or
+-- buffers). Where a 0 appears, the corresponding bit is write-protected.
+--
+-- This mask is used only in color index mode, and it affects only the buffers
+-- currently selected for writing (see 'drawBuffer'). Initially, all bits are
+-- enabled for writing.
+
+indexMask :: StateVar GLuint
+indexMask =
+   makeStateVar (getInteger1 fromIntegral GetIndexWritemask) glIndexMask
+
+foreign import CALLCONV unsafe "glIndexMask" glIndexMask :: GLuint -> IO ()
+
+--------------------------------------------------------------------------------
+
+-- | Controls whether the individual color components in the framebuffer can or
+-- cannot be written. If the red flag is 'Disabled', for example, no change is
+-- made to the red component of any pixel in any of the color buffers,
+-- regardless of the drawing operation attempted. Initially, all color
+-- components can be written.
+--
+-- Changes to individual bits of components cannot be controlled. Rather,
+-- changes are either enabled or disabled for entire color components.
+-- Furthermore, this mask is used only in RGBA mode.
+
+colorMask :: StateVar (Color4 Capability)
+colorMask =
+   makeStateVar
+      (getBoolean4 (\r g b a -> Color4 (unmarshalCapability r)
+                                       (unmarshalCapability g)
+                                       (unmarshalCapability b)
+                                       (unmarshalCapability a))
+                                      GetColorWritemask)
+      (\(Color4 r g b a) -> glColorMask (marshalCapability r)
+                                        (marshalCapability g)
+                                        (marshalCapability b)
+                                        (marshalCapability a))
+
+foreign import CALLCONV unsafe "glColorMask" glColorMask ::
+   GLboolean -> GLboolean -> GLboolean -> GLboolean -> IO ()
+
+--------------------------------------------------------------------------------
+
+-- | Controls whether the depth buffer is enabled for writing. The initial state
+-- is 'Enabled'.
+
+depthMask :: StateVar Capability
+depthMask = makeStateVar (getBoolean1 unmarshalCapability GetDepthWritemask)
+                         (glDepthMask . marshalCapability)
+
+foreign import CALLCONV unsafe "glDepthMask" glDepthMask :: GLboolean -> IO ()
+
+--------------------------------------------------------------------------------
+
+-- | Controls the writing of individual bits in the stencil planes. The least
+-- significant /n/ bits of its value, where /n/ is the number of bits in the
+-- stencil buffer, specify a mask. Where a 1 appears in the mask, it is
+-- possible to write to the corresponding bit in the stencil buffer. Where a 0
+-- appears, the corresponding bit is write-protected.
+-- Initially, all bits are enabled for writing.
+
+stencilMask :: StateVar GLuint
+stencilMask =
+   makeStateVar (getInteger1 fromIntegral GetStencilWritemask) glStencilMask
+
+foreign import CALLCONV unsafe "glStencilMask" glStencilMask :: GLuint -> IO ()
+
+stencilMaskSeparate :: Face -> SettableStateVar GLuint
+stencilMaskSeparate face =
+   makeSettableStateVar $
+      glStencilMaskSeparate (marshalFace face)
+
+EXTENSION_ENTRY("OpenGL 2.0",glStencilMaskSeparate,GLenum -> GLuint -> IO ())
+
+--------------------------------------------------------------------------------
+
+-- | The buffers which can be cleared with 'clear'.
+
+data ClearBuffer =
+     ColorBuffer   -- ^ The buffers currently enabled for color writing.
+   | AccumBuffer   -- ^ The accumulation buffer.
+   | StencilBuffer -- ^ The stencil buffer.
+   | DepthBuffer   -- ^ The depth buffer.
+   deriving ( Eq, Ord, Show )
+
+marshalClearBuffer :: ClearBuffer -> GLbitfield
+marshalClearBuffer x = case x of
+   ColorBuffer -> 0x4000
+   AccumBuffer -> 0x200
+   StencilBuffer -> 0x400
+   DepthBuffer -> 0x100
+
+--------------------------------------------------------------------------------
+
+-- | Set the bitplane area of the window to values previously selected by
+-- 'clearColor', 'clearIndex', 'clearDepth', 'clearStencil', and 'clearAccum'.
+-- Multiple color buffers can be cleared simultaneously by selecting more than
+-- one buffer at a time using 'drawBuffer'.
+--
+-- The pixel ownership test, the scissor test, dithering, and the buffer
+-- writemasks affect the operation of 'clear'. The scissor box bounds the
+-- cleared region. Alpha function, blend function, logical operation,
+-- stenciling, texure mapping, and depth-buffering are ignored by 'clear'.
+--
+-- 'clear' takes a list of buffers, indicating which buffers are to be cleared.
+-- If a buffer is not present, then a 'clear' directed at that buffer has no
+-- effect.
+--
+-- The value to which each buffer is cleared depends on the setting of the clear
+-- value for that buffer.
+
+clear :: [ClearBuffer] -> GL ()
+clear = glClear . sum . map marshalClearBuffer
+
+foreign import CALLCONV unsafe "glClear" glClear :: GLbitfield -> GL ()
+
+--------------------------------------------------------------------------------
+
+-- | Controls the red, green, blue, and alpha values used by 'clear' to clear
+-- the color buffers. Values written into 'clearColor' are clamped to the range
+-- [0, 1]. Initially, all values are 0.
+
+clearColor :: StateVar (Color4 GLclampf)
+clearColor = makeStateVar (getFloat4 Color4 GetColorClearValue)
+                          (\(Color4 r g b a) -> glClearColor r g b a)
+
+foreign import CALLCONV unsafe "glClearColor" glClearColor ::
+    GLclampf -> GLclampf -> GLclampf -> GLclampf -> IO ()
+
+--------------------------------------------------------------------------------
+
+-- | Controls the index /c/ used by 'clear' to clear the color index buffers.
+-- /c/ is not clamped. Rather, /c/ is converted to a fixed-point value with
+-- unspecified precision to the right of the binary point. The integer part of
+-- this value is then masked with 2^/m/-1, where /m/ is the number of bits in a
+-- color index stored in the framebuffer. Initially, the value is 0.
+
+clearIndex :: StateVar (Index1 GLfloat)
+clearIndex = makeStateVar (getFloat1 Index1 GetIndexClearValue)
+                          (\(Index1 i) -> glClearIndex i)
+
+foreign import CALLCONV unsafe "glClearIndex" glClearIndex :: GLfloat -> IO ()
+
+--------------------------------------------------------------------------------
+
+-- | Controls the depth value used by 'clear' to clear the depth buffer. Values
+-- written into 'clearDepth' are clamped to the range [0, 1]. The initial value
+-- is 1.
+
+clearDepth :: StateVar GLclampd
+clearDepth = makeStateVar (getDouble1 id GetDepthClearValue) glClearDepth
+
+foreign import CALLCONV unsafe "glClearDepth" glClearDepth :: GLclampd -> IO ()
+
+--------------------------------------------------------------------------------
+
+-- | Controls the value /s/ used by 'clear' to clear the stencil buffer. /s/ is
+-- masked with 2^/m/-1, where /m/ is the number of bits in the stencil buffer.
+-- Initially, the value is 0.
+
+clearStencil :: StateVar GLint
+clearStencil = makeStateVar (getInteger1 id GetStencilClearValue) glClearStencil
+
+foreign import CALLCONV unsafe "glClearStencil" glClearStencil :: GLint -> IO ()
+
+--------------------------------------------------------------------------------
+
+-- | Controls the red, green, blue, and alpha values used by 'clear' to clear
+-- the accumulation buffer. Values written into 'clearAccum' are clamped to the
+-- range [-1, 1]. The initial values are all 0.
+
+clearAccum :: StateVar (Color4 GLfloat)
+clearAccum =
+   makeStateVar (getFloat4 Color4 GetAccumClearValue)
+                (\(Color4 r g b a) -> glClearAccum r g b a)
+
+foreign import CALLCONV unsafe "glClearAccum" glClearAccum ::
+   GLfloat -> GLfloat -> GLfloat -> GLfloat -> IO ()
+
+--------------------------------------------------------------------------------
+
+-- | An operation on the accumulation buffer.
+
+data AccumOp =
+     Accum
+     -- ^ Obtains /R/, /G/, /B/, and /A/ values from the buffer currently
+     -- selected for reading (see
+     -- 'Graphics.Rendering.OGL.GL.ReadCopyPixels.readBuffer'). Each
+     -- component value is divided by 2^/n/-1, where /n/ is the number of bits
+     -- allocated to each color component in the currently selected buffer. The
+     -- result is a floating-point value in the range [0, 1], which is
+     -- multiplied by the value given to 'accum' and added to the corresponding
+     -- pixel component in the accumulation buffer, thereby updating the
+     -- accumulation buffer.
+   | Load
+     -- ^ Similar to 'Accum', except that the current value in the accumulation
+     -- buffer is not used in the calculation of the new value. That is, the
+     -- /R/, /G/, /B/, and /A/ values from the currently selected buffer are
+     -- divided by 2^/n/-1, multiplied by the value given to 'accum', and then
+     -- stored in the corresponding accumulation buffer cell, overwriting the
+     -- current value.
+   | Return
+     -- ^ Transfers accumulation buffer values to the color buffer or buffers
+     -- currently selected for writing. Each /R/, /G/, /B/, and /A/ component
+     -- is multiplied by the value given to 'accum', then multiplied by 2^/n/-1,
+     -- clamped to the range [0, 2^/n/-1], and stored in the corresponding
+     -- display buffer cell. The only fragment operations that are applied to
+     -- this transfer are pixel ownership, scissor, dithering, and color
+     -- writemasks.
+   | Mult
+     -- ^ Multiplies each /R/, /G/, /B/, and /A/ in the accumulation buffer by
+     -- the value given to 'accum' and returns the scaled component to its
+     -- corresponding accumulation buffer location.
+   | Add
+     -- ^ Adds the value given to 'accum' to each /R/, /G/, /B/, and /A/ in the
+     -- accumulation buffer.
+   deriving ( Eq, Ord, Show )
+
+marshalAccumOp :: AccumOp -> GLenum
+marshalAccumOp x = case x of
+   Accum -> 0x100
+   Load -> 0x101
+   Return -> 0x102
+   Mult -> 0x103
+   Add -> 0x104
+
+--------------------------------------------------------------------------------
+
+-- | The accumulation buffer is an extended-range color buffer. Images are not
+-- rendered into it. Rather, images rendered into one of the color buffers are
+-- added to the contents of the accumulation buffer after rendering. Effects
+-- such as antialiasing (of points, lines, and polygons), motion blur, and
+-- depth of field can be created by accumulating images generated with different
+-- transformation matrices.
+--
+-- Each pixel in the accumulation buffer consists of red, green, blue, and alpha
+-- values. The number of bits per component in the accumulation buffer depends
+-- on the implementation (see 'accumBits'). Regardless of the number of bits per
+-- component, the range of values stored by each component is [-1, 1]. The
+-- accumulation buffer pixels are mapped one-to-one with frame buffer pixels.
+--
+-- 'accum' operates on the accumulation buffer. The first argument selects an
+-- accumulation buffer operation. The second argument, is a floating-point value
+-- to be used in that operation, see 'AccumOp'.
+--
+-- All accumulation buffer operations are limited to the area of the current
+-- scissor box and applied identically to the red, green, blue, and alpha
+-- components of each pixel. If an 'accum' operation results in a value outside
+-- the range [-1, 1], the contents of an accumulation buffer pixel component
+-- are undefined.
+--
+-- To clear the accumulation buffer, use 'clearAccum' to specify the clear
+-- value, then call 'clear' with the accumulation buffer enabled.
+
+accum :: AccumOp -> GLfloat -> GL ()
+accum = glAccum . marshalAccumOp
+
+foreign import CALLCONV unsafe "glAccum" glAccum :: GLenum -> GLfloat -> GL ()
diff --git a/Graphics/Rendering/OGL/GL/GLboolean.hs b/Graphics/Rendering/OGL/GL/GLboolean.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/GLboolean.hs
@@ -0,0 +1,27 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.GLboolean
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for (un-)marshaling GLboolean.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.GLboolean (
+   marshalGLboolean, unmarshalGLboolean
+) where
+
+--------------------------------------------------------------------------------
+
+marshalGLboolean :: Num a => Bool -> a
+marshalGLboolean False = 0
+marshalGLboolean True  = 1
+
+unmarshalGLboolean :: Num a => a -> Bool
+unmarshalGLboolean = (/= 0)
diff --git a/Graphics/Rendering/OGL/GL/Hints.hs b/Graphics/Rendering/OGL/GL/Hints.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Hints.hs
@@ -0,0 +1,95 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Hints
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 5.6 (Hints) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Hints (
+   HintTarget(..), HintMode(..), hint
+) where
+
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetPerspectiveCorrectionHint,GetPointSmoothHint,GetLineSmoothHint,
+            GetPolygonSmoothHint,GetFogHint,GetGenerateMipmapHint,
+            GetTextureCompressionHint,GetPackCMYKHint,GetUnpackCMYKHint),
+   getEnum1 )
+import Graphics.Rendering.OGL.GL.StateVar ( StateVar, makeStateVar )
+
+import Graphics.Rendering.OGL.Monad
+--------------------------------------------------------------------------------
+
+data HintTarget =
+     PerspectiveCorrection
+   | PointSmooth
+   | LineSmooth
+   | PolygonSmooth
+   | Fog
+   | GenerateMipmap
+   | TextureCompression
+   | PackCMYK
+   | UnpackCMYK
+   deriving ( Eq, Ord, Show )
+
+marshalHintTarget :: HintTarget -> GLenum
+marshalHintTarget x = case x of
+   PerspectiveCorrection -> 0xc50
+   PointSmooth -> 0xc51
+   LineSmooth -> 0xc52
+   PolygonSmooth -> 0xc53
+   Fog -> 0xc54
+   GenerateMipmap -> 0x8192
+   TextureCompression -> 0x84ef
+   PackCMYK -> 0x800e
+   UnpackCMYK -> 0x800f
+
+hintTargetToGetPName :: HintTarget -> GetPName
+hintTargetToGetPName x = case x of
+   PerspectiveCorrection -> GetPerspectiveCorrectionHint
+   PointSmooth -> GetPointSmoothHint
+   LineSmooth -> GetLineSmoothHint
+   PolygonSmooth -> GetPolygonSmoothHint
+   Fog -> GetFogHint
+   GenerateMipmap -> GetGenerateMipmapHint
+   TextureCompression -> GetTextureCompressionHint
+   PackCMYK -> GetPackCMYKHint
+   UnpackCMYK -> GetUnpackCMYKHint
+
+--------------------------------------------------------------------------------
+
+data HintMode =
+     DontCare
+   | Fastest
+   | Nicest
+   deriving ( Eq, Ord, Show )
+
+marshalHintMode :: HintMode -> GLenum
+marshalHintMode x = case x of
+   DontCare -> 0x1100
+   Fastest -> 0x1101
+   Nicest -> 0x1102
+
+unmarshalHintMode :: GLenum -> HintMode
+unmarshalHintMode x
+   | x == 0x1100 = DontCare
+   | x == 0x1101 = Fastest
+   | x == 0x1102 = Nicest
+   | otherwise = error ("unmarshalHintMode: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+hint ::  HintTarget -> StateVar HintMode
+hint t =
+   makeStateVar
+      (getEnum1 unmarshalHintMode (hintTargetToGetPName t))
+      (glHint (marshalHintTarget t) . marshalHintMode)
+
+foreign import CALLCONV unsafe "glHint" glHint :: GLenum -> GLenum -> IO ()
diff --git a/Graphics/Rendering/OGL/GL/IOState.hs b/Graphics/Rendering/OGL/GL/IOState.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/IOState.hs
@@ -0,0 +1,57 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.IOState
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for an IO monad with a pointer as an
+-- additional state, basically a /StateT (Ptr s) IO a/.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.IOState (
+   IOState(..), getIOState, peekIOState, evalIOState, nTimes
+) where
+
+import Foreign.Ptr ( Ptr, plusPtr )
+import Foreign.Storable ( Storable(sizeOf,peek) )
+import Graphics.Rendering.OGL.Monad
+
+--------------------------------------------------------------------------------
+
+newtype IOState s a = IOState { runIOState :: Ptr s -> IO (a, Ptr s) }
+
+instance Functor (IOState s) where
+   fmap f m = IOState $ \s -> do (x, s') <- runIOState m s ; return (f x, s')
+
+instance Monad (IOState s) where
+   return a = IOState $ \s -> return (a, s)
+   m >>= k  = IOState $ \s -> do (a, s') <- runIOState m s ; runIOState (k a) s'
+   fail str = IOState $ \_ -> fail str
+
+getIOState :: IOState s (Ptr s)
+getIOState = IOState $ \s -> return (s, s)
+
+putIOState :: Ptr s -> IOState s ()
+putIOState s = IOState $ \_ -> return ((), s)
+
+peekIOState :: Storable a => IOState a a
+peekIOState = do
+   ptr <- getIOState
+   x <- liftIOState $ peek ptr
+   putIOState (ptr `plusPtr` sizeOf x)
+   return x
+
+liftIOState :: IO a -> IOState s a
+liftIOState m = IOState $ \s -> do a <- m ; return (a, s)
+
+evalIOState :: IOState s a -> Ptr s -> IO a
+evalIOState m s = do (a, _) <- runIOState m s ; return a
+
+nTimes :: Integral a => a -> IOState b c -> IOState b [c]
+nTimes n = sequence . replicate (fromIntegral n)
diff --git a/Graphics/Rendering/OGL/GL/LineSegments.hs b/Graphics/Rendering/OGL/GL/LineSegments.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/LineSegments.hs
@@ -0,0 +1,163 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.LineSegments
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.4 (Line Segments) of the OpenGL 2.1
+-- specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.LineSegments (
+   -- * Line Rasterization
+   lineWidth,
+
+   -- * Line Stipple
+   lineStipple,
+
+   -- * Line Antialiasing
+  lineSmooth,
+
+   -- * Implementation-Dependent Limits
+   aliasedLineWidthRange, smoothLineWidthRange, smoothLineWidthGranularity
+) where
+
+import Control.Monad ( liftM2 )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapLineSmooth,CapLineStipple), makeCapability, makeStateVarMaybe )
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLint, GLushort, GLfloat, Capability )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetLineWidth,GetAliasedLineWidthRange,GetSmoothLineWidthRange,
+            GetSmoothLineWidthGranularity,GetLineStippleRepeat,
+            GetLineStipplePattern),
+   getInteger1, getFloat1, getFloat2 )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )
+
+--------------------------------------------------------------------------------
+
+-- | 'lineWidth' contains the rasterized width of both aliased and antialiased
+-- lines. The initial value is 1. Using a line width other than 1 has different
+-- effects, depending on whether line antialiasing is enabled (see
+-- 'lineSmooth'). Line antialiasing is initially disabled.
+--
+-- If line antialiasing is disabled, the actual width is determined by rounding
+-- the supplied width to the nearest integer. (If the rounding results in the
+-- value 0, it is as if the line width were 1.) If /delta x/ >= /delta y/, /i/
+-- pixels are filled in each column that is rasterized, where /i/ is the
+-- rounded value of 'lineWidth'. Otherwise, /i/ pixels are filled in each row
+-- that is rasterized.
+--
+-- If antialiasing is enabled, line rasterization produces a fragment for each
+-- pixel square that intersects the region lying within the rectangle having
+-- width equal to the current line width, length equal to the actual length of
+-- the line, and centered on the mathematical line segment. The coverage value
+-- for each fragment is the window coordinate area of the intersection of the
+-- rectangular region with the corresponding pixel square. This value is saved
+-- and used in the final rasterization step.
+--
+-- Not all widths can be supported when line antialiasing is enabled. If an
+-- unsupported width is requested, the nearest supported width is used. Only
+-- width 1 is guaranteed to be supported; others depend on the implementation.
+--  Likewise, there is a range for aliased line widths as well. To query the
+-- range of supported widths of antialiased lines and the size difference
+-- between supported widths within the range, query 'smoothLineWidthRange' and
+-- 'smoothLineWidthGranularity', respectively. For aliased lines, query the
+-- supported range with 'aliasedLineWidthRange'.
+--
+-- The line width specified when 'lineWidth' is set is always returned when it
+-- is queried. Clamping and rounding for aliased and antialiased lines have no
+-- effect on the specified value.
+--
+-- A non-antialiased line width may be clamped to an implementation-dependent
+-- maximum.  Query 'aliasedLineWidthRange' to determine the maximum width.
+--
+-- An 'Graphics.Rendering.OGL.GLU.Errors.InvalidValue' is generated if
+-- 'lineWidth' is set to a value less than or equal to zero.
+--
+-- An 'Graphics.Rendering.OGL.GLU.Errors.InvalidOperation' is generated if
+-- 'lineWidth' is set during
+-- 'Graphics.Rendering.OGL.GL.BeginEnd.renderPrimitive'.
+
+lineWidth :: StateVar GLfloat
+lineWidth = makeStateVar (getFloat1 id GetLineWidth) glLineWidth
+
+foreign import CALLCONV unsafe "glLineWidth" glLineWidth :: GLfloat -> IO ()
+
+--------------------------------------------------------------------------------
+
+-- | Line stippling masks out certain fragments produced by rasterization; those
+-- fragments will not be drawn. The masking is achieved by using three
+-- parameters: the repeat count (1st element of the 'lineStipple' pair, clamped
+-- to the range [ 1 .. 256 ]), the 16-bit line stipple pattern (2nd element),
+-- and an integer stipple counter /s/.
+--
+-- The counter /s/ is reset to 0 at before the first action during
+-- 'Graphics.Rendering.OGL.GL.BeginEnd.renderPrimitive' is called and before
+-- each line segment during
+-- 'Graphics.Rendering.OGL.GL.BeginEnd.renderPrimitive' is generated. It is
+-- incremented after each fragment of a unit width aliased line segment is
+-- generated or after each /i/ fragments of an /i/ width line segment are
+-- generated. The /i/ fragments associated with count /s/ are masked out if
+-- @'Data.Bits.testBit' /pattern/ (( /s/ \/ /factor/ ) /mod/ 16)@ is 'False',
+-- otherwise these fragments are sent to the frame buffer. Bit zero of the
+-- pattern is the least significant bit, i.e. it is used first.
+--
+-- Antialiased lines are treated as a sequence of rectangles of height 1 for
+-- purposes of stippling. Whether rectangle /s/ is rasterized or not depends on
+-- the fragment rule described for aliased lines, counting rectangles rather
+-- than groups of fragments.
+--
+-- The initial value of 'lineStipple' is 'Nothing', i.e. line stippling is
+-- disabled.
+--
+-- An 'Graphics.Rendering.OGL.GLU.Errors.InvalidOperation' is generated if
+-- 'lineStipple' is set during
+-- 'Graphics.Rendering.OGL.GL.BeginEnd.renderPrimitive'.
+
+lineStipple :: StateVar (Maybe (GLint, GLushort))
+lineStipple =
+   makeStateVarMaybe
+      (return CapLineStipple)
+      (liftM2 (,) (getInteger1 id GetLineStippleRepeat)
+                  (getInteger1 fromIntegral GetLineStipplePattern))
+      (uncurry glLineStipple)
+
+foreign import CALLCONV unsafe "glLineStipple" glLineStipple ::
+   GLint -> GLushort -> IO ()
+
+--------------------------------------------------------------------------------
+
+-- | Controls whether line antialiasing is enabled. The initial state is
+-- 'Graphics.Rendering.OGL.GL.BasicTypes.Disabled'.
+
+lineSmooth :: StateVar Capability
+lineSmooth = makeCapability CapLineSmooth
+
+--------------------------------------------------------------------------------
+
+-- | The smallest and largest supported width of aliased lines.
+
+aliasedLineWidthRange :: GettableStateVar (GLfloat, GLfloat)
+aliasedLineWidthRange =
+   makeGettableStateVar $ getFloat2 (,) GetAliasedLineWidthRange
+
+-- | The smallest and largest supported width of antialiased lines.
+
+smoothLineWidthRange :: GettableStateVar (GLfloat, GLfloat)
+smoothLineWidthRange =
+   makeGettableStateVar $ getFloat2 (,) GetSmoothLineWidthRange
+
+-- | The antialiased line width granularity, i.e. the size difference between
+-- supported widths.
+
+smoothLineWidthGranularity :: GettableStateVar GLfloat
+smoothLineWidthGranularity =
+   makeGettableStateVar $ getFloat1 id GetSmoothLineWidthGranularity
diff --git a/Graphics/Rendering/OGL/GL/PeekPoke.hs b/Graphics/Rendering/OGL/GL/PeekPoke.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PeekPoke.hs
@@ -0,0 +1,87 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PeekPoke
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module with peek- and poke-related utilities.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PeekPoke (
+   poke1, poke2, poke3, poke4,
+   peek1, peek2, peek3, peek4
+) where
+
+import Foreign.Ptr ( Ptr )
+import Foreign.Storable ( Storable(peekElemOff,pokeElemOff) )
+import Graphics.Rendering.OGL.Monad
+
+--------------------------------------------------------------------------------
+-- The implementation is little bit verbose/redundant, but seems to generate
+-- better code than mapM/zipWithM_.
+
+--------------------------------------------------------------------------------
+
+{-# INLINE poke1 #-}
+poke1 :: Storable a => Ptr a -> a -> IO ()
+poke1 ptr x =
+   pokeElemOff ptr 0 x
+
+{-# INLINE poke2 #-}
+poke2 :: Storable a => Ptr a -> a -> a -> IO ()
+poke2 ptr x y = do
+   pokeElemOff ptr 0 x
+   pokeElemOff ptr 1 y
+
+{-# INLINE poke3 #-}
+poke3 :: Storable a => Ptr a -> a -> a -> a -> IO ()
+poke3 ptr x y z = do
+   pokeElemOff ptr 0 x
+   pokeElemOff ptr 1 y
+   pokeElemOff ptr 2 z
+
+{-# INLINE poke4 #-}
+poke4 :: Storable a => Ptr a -> a -> a -> a -> a -> IO ()
+poke4 ptr x y z w = do
+   pokeElemOff ptr 0 x
+   pokeElemOff ptr 1 y
+   pokeElemOff ptr 2 z
+   pokeElemOff ptr 3 w
+
+--------------------------------------------------------------------------------
+
+{-# INLINE peek1 #-}
+peek1 :: Storable a => (a -> b) -> Ptr a -> IO b
+peek1 f ptr = do
+   x <- peekElemOff ptr 0
+   return $ f x
+
+{-# INLINE peek2 #-}
+peek2 :: Storable a => (a -> a -> b) -> Ptr a -> IO b
+peek2 f ptr = do
+   x <- peekElemOff ptr 0
+   y <- peekElemOff ptr 1
+   return $ f x y
+
+{-# INLINE peek3 #-}
+peek3 :: Storable a => (a -> a -> a -> b) -> Ptr a -> IO b
+peek3 f ptr = do
+   x <- peekElemOff ptr 0
+   y <- peekElemOff ptr 1
+   z <- peekElemOff ptr 2
+   return $ f x y z
+
+{-# INLINE peek4 #-}
+peek4 :: Storable a => (a -> a -> a -> a -> b) -> Ptr a -> IO b
+peek4 f ptr = do
+   x <- peekElemOff ptr 0
+   y <- peekElemOff ptr 1
+   z <- peekElemOff ptr 2
+   w <- peekElemOff ptr 3
+   return $ f x y z w
diff --git a/Graphics/Rendering/OGL/GL/PerFragment.hs b/Graphics/Rendering/OGL/GL/PerFragment.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PerFragment.hs
@@ -0,0 +1,544 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PerFragment
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 4.1 (Per-Fragment Operations) of the
+-- OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PerFragment (
+   -- * Scissor Test
+   scissor,
+
+   -- * Multisample Fragment Operations
+   sampleAlphaToCoverage,  sampleAlphaToOne, sampleCoverage,
+
+   -- * Depth Bounds Test
+   depthBounds,
+
+   -- * Alpha Test
+   ComparisonFunction(..), alphaFunc,
+
+   -- * Stencil Test
+   stencilTest, stencilFunc, stencilFuncSeparate, StencilOp(..), stencilOp,
+   stencilOpSeparate, activeStencilFace,
+
+   -- * Depth Buffer Test
+   depthFunc,
+
+   -- * Occlusion Queries
+   QueryObject(QueryObject), QueryTarget(..), withQuery,
+   queryCounterBits, currentQuery,
+   queryResult, queryResultAvailable,
+
+   -- * Blending
+   blend, BlendEquation(..), blendEquation, blendEquationSeparate,
+   BlendingFactor(..), blendFuncSeparate, blendFunc, blendColor,
+
+   -- * Dithering
+   dither,
+
+   -- * Logical Operation
+   LogicOp(..), logicOp
+) where
+
+import Control.Monad ( liftM2, liftM3 )
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Marshal.Array ( withArrayLen, peekArray, allocaArray )
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BufferObjects ( ObjectName(..) )
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapScissorTest,CapSampleAlphaToCoverage,CapSampleAlphaToOne,
+             CapSampleCoverage,CapDepthBoundsTest,CapAlphaTest,CapStencilTest,
+             CapStencilTestTwoSide,CapDepthTest,CapBlend,CapDither,
+             CapIndexLogicOp,CapColorLogicOp),
+   makeCapability, makeStateVarMaybe )
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLboolean, GLint, GLuint, GLsizei, GLenum, GLclampf, GLclampd, Capability )
+import Graphics.Rendering.OGL.GL.BlendingFactor (
+   BlendingFactor(..), marshalBlendingFactor, unmarshalBlendingFactor )
+import Graphics.Rendering.OGL.GL.ComparisonFunction ( ComparisonFunction(..),
+   marshalComparisonFunction, unmarshalComparisonFunction )
+import Graphics.Rendering.OGL.GL.CoordTrans ( Position(..), Size(..) )
+import Graphics.Rendering.OGL.GL.Exception ( bracket_ )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.Face ( marshalFace, unmarshalFace )
+import Graphics.Rendering.OGL.GL.Colors ( Face )
+import Graphics.Rendering.OGL.GL.GLboolean (
+   marshalGLboolean, unmarshalGLboolean )
+import Graphics.Rendering.OGL.GL.PeekPoke ( peek1 )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetScissorBox,GetSampleCoverageValue,GetSampleCoverageInvert,
+            GetDepthBounds,GetAlphaTestFunc,GetAlphaTestRef,GetStencilFunc,
+            GetStencilRef,GetStencilValueMask,GetStencilFail,
+            GetStencilPassDepthFail,GetStencilPassDepthPass,
+            GetActiveStencilFace,GetDepthFunc,GetBlendEquation,
+            GetBlendEquationAlpha,GetBlendDstRGB,GetBlendSrcRGB,
+            GetBlendDstAlpha,GetBlendSrcAlpha,GetBlendSrc,GetBlendDst,
+            GetBlendColor,GetLogicOpMode),
+   getInteger1, getInteger4, getEnum1, getFloat1, getFloat4, getDouble2,
+   getBoolean1 )
+import Graphics.Rendering.OGL.GL.StateVar (
+   getIO, GettableStateVar, makeGettableStateVar,
+   SettableStateVar, makeSettableStateVar,
+   StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.VertexSpec ( Color4(..), rgbaMode )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+
+--------------------------------------------------------------------------------
+
+scissor :: StateVar (Maybe (Position, Size))
+scissor =
+   makeStateVarMaybe
+      (return CapScissorTest)
+      (getInteger4 makeSB GetScissorBox)
+      (\(Position x y, Size w h) -> glScissor x y w h)
+   where makeSB x y w h = (Position x y, Size (fromIntegral w) (fromIntegral h))
+       
+foreign import CALLCONV unsafe "glScissor" glScissor ::
+   GLint -> GLint -> GLsizei -> GLsizei -> IO ()
+
+--------------------------------------------------------------------------------
+
+sampleAlphaToCoverage :: StateVar Capability
+sampleAlphaToCoverage = makeCapability CapSampleAlphaToCoverage
+
+sampleAlphaToOne :: StateVar Capability
+sampleAlphaToOne = makeCapability CapSampleAlphaToOne
+
+sampleCoverage :: StateVar (Maybe (GLclampf, Bool))
+sampleCoverage =
+   makeStateVarMaybe
+      (return CapSampleCoverage)
+      (liftM2 (,) (getFloat1 id GetSampleCoverageValue)
+                  (getBoolean1 unmarshalGLboolean GetSampleCoverageInvert))
+      (\(value, invert) -> glSampleCoverageARB value (marshalGLboolean invert))
+
+EXTENSION_ENTRY("GL_ARB_multisample or OpenGL 1.3",glSampleCoverageARB,GLclampf -> GLboolean -> IO ())
+
+--------------------------------------------------------------------------------
+
+depthBounds :: StateVar (Maybe (GLclampd, GLclampd))
+depthBounds =
+   makeStateVarMaybe
+      (return CapDepthBoundsTest)
+      (getDouble2 (,) GetDepthBounds)
+      (uncurry glDepthBoundsEXT)
+       
+EXTENSION_ENTRY("GL_EXT_depth_bounds_test",glDepthBoundsEXT,GLclampd -> GLclampd -> IO ())
+
+--------------------------------------------------------------------------------
+
+alphaFunc :: StateVar (Maybe (ComparisonFunction, GLclampf))
+alphaFunc =
+   makeStateVarMaybe
+      (return CapAlphaTest)
+      (liftM2 (,) (getEnum1 unmarshalComparisonFunction GetAlphaTestFunc)
+                  (getFloat1 id GetAlphaTestRef))
+      (uncurry (glAlphaFunc . marshalComparisonFunction))
+
+foreign import CALLCONV unsafe "glAlphaFunc" glAlphaFunc ::
+   GLenum -> GLclampf -> IO ()
+
+--------------------------------------------------------------------------------
+
+stencilTest :: StateVar Capability
+stencilTest = makeCapability CapStencilTest
+
+--------------------------------------------------------------------------------
+
+stencilFunc :: StateVar (ComparisonFunction, GLint, GLuint)
+stencilFunc =
+   makeStateVar
+      (liftM3 (,,) (getEnum1 unmarshalComparisonFunction GetStencilFunc)
+                   (getInteger1 id GetStencilRef)
+                   (getInteger1 fromIntegral GetStencilValueMask))
+      (\(func, ref, mask) ->
+         glStencilFunc (marshalComparisonFunction func) ref mask)
+
+foreign import CALLCONV unsafe "glStencilFunc" glStencilFunc ::
+   GLenum -> GLint -> GLuint -> IO ()
+
+stencilFuncSeparate :: Face -> SettableStateVar (ComparisonFunction, GLint, GLuint)
+stencilFuncSeparate face =
+   makeSettableStateVar $ \(func, ref, mask) ->
+      glStencilFuncSeparate (marshalFace face) (marshalComparisonFunction func) ref mask
+
+EXTENSION_ENTRY("OpenGL 2.0",glStencilFuncSeparate,GLenum -> GLenum -> GLint -> GLuint -> IO ())
+
+--------------------------------------------------------------------------------
+
+data StencilOp =
+     OpZero
+   | OpKeep
+   | OpReplace
+   | OpIncr
+   | OpIncrWrap
+   | OpDecr
+   | OpDecrWrap
+   | OpInvert
+   deriving ( Eq, Ord, Show )
+
+marshalStencilOp :: StencilOp -> GLenum
+marshalStencilOp x = case x of
+   OpZero -> 0x0
+   OpKeep -> 0x1e00
+   OpReplace -> 0x1e01
+   OpIncr -> 0x1e02
+   OpIncrWrap -> 0x8507
+   OpDecr -> 0x1e03
+   OpDecrWrap -> 0x8508
+   OpInvert -> 0x150a
+
+unmarshalStencilOp :: GLenum -> StencilOp
+unmarshalStencilOp x
+   | x == 0x0 = OpZero
+   | x == 0x1e00 = OpKeep
+   | x == 0x1e01 = OpReplace
+   | x == 0x1e02 = OpIncr
+   | x == 0x8507 = OpIncrWrap
+   | x == 0x1e03 = OpDecr
+   | x == 0x8508 = OpDecrWrap
+   | x == 0x150a = OpInvert
+   | otherwise = error ("unmarshalStencilOp: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+stencilOp :: StateVar (StencilOp, StencilOp, StencilOp)
+stencilOp =
+   makeStateVar
+      (liftM3 (,,) (getEnum1 unmarshalStencilOp GetStencilFail)
+                   (getEnum1 unmarshalStencilOp GetStencilPassDepthFail)
+                   (getEnum1 unmarshalStencilOp GetStencilPassDepthPass))
+      (\(sf, spdf, spdp) -> glStencilOp (marshalStencilOp sf)
+                                        (marshalStencilOp spdf)
+                                        (marshalStencilOp spdp))
+
+foreign import CALLCONV unsafe "glStencilOp" glStencilOp ::
+   GLenum -> GLenum -> GLenum -> IO ()
+
+stencilOpSeparate :: Face -> SettableStateVar (StencilOp, StencilOp, StencilOp)
+stencilOpSeparate face =
+   makeSettableStateVar $ \(sf, spdf, spdp) ->
+      glStencilOpSeparate (marshalFace face)
+                          (marshalStencilOp sf)
+                          (marshalStencilOp spdf)
+                          (marshalStencilOp spdp)
+
+EXTENSION_ENTRY("OpenGL 2.0",glStencilOpSeparate,GLenum -> GLenum -> GLenum -> GLenum -> IO ())
+
+--------------------------------------------------------------------------------
+
+activeStencilFace :: StateVar (Maybe Face)
+activeStencilFace =
+   makeStateVarMaybe
+      (return CapStencilTestTwoSide)
+      (getEnum1 unmarshalFace GetActiveStencilFace)
+      (glActiveStencilFaceEXT . marshalFace)
+
+EXTENSION_ENTRY("GL_EXT_stencil_two_side",glActiveStencilFaceEXT,GLenum -> IO ())
+
+--------------------------------------------------------------------------------
+
+depthFunc :: StateVar (Maybe ComparisonFunction)
+depthFunc =
+   makeStateVarMaybe
+      (return CapDepthTest)
+      (getEnum1 unmarshalComparisonFunction GetDepthFunc)
+      (glDepthFunc . marshalComparisonFunction)
+
+foreign import CALLCONV unsafe "glDepthFunc" glDepthFunc :: GLenum -> IO ()
+
+--------------------------------------------------------------------------------
+
+newtype QueryObject = QueryObject { queryID :: GLuint }
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+instance ObjectName QueryObject where
+   genObjectNames n = liftIO .
+      allocaArray n $ \buf -> do
+        glGenQueriesARB (fromIntegral n) buf
+        fmap (map QueryObject) $ peekArray n buf
+
+   deleteObjectNames queryObjects = liftIO .
+      withArrayLen (map queryID queryObjects) $
+         glDeleteQueriesARB . fromIntegral
+
+   isObjectName = liftIO . fmap unmarshalGLboolean . glIsQueryARB . queryID
+
+
+EXTENSION_ENTRY("GL_ARB_occlusion_query or OpenGL 1.5",glGenQueriesARB,GLsizei -> Ptr GLuint -> IO ())
+
+EXTENSION_ENTRY("GL_ARB_occlusion_query or OpenGL 1.5",glDeleteQueriesARB,GLsizei -> Ptr GLuint -> IO ())
+
+EXTENSION_ENTRY("GL_ARB_occlusion_query or OpenGL 1.5",glIsQueryARB,GLuint -> IO GLboolean)
+
+--------------------------------------------------------------------------------
+
+data QueryTarget =
+     SamplesPassed
+   deriving ( Eq, Ord, Show )
+
+marshalQueryTarget :: QueryTarget -> GLenum
+marshalQueryTarget x = case x of
+   SamplesPassed -> 0x8914
+
+--------------------------------------------------------------------------------
+
+beginQuery :: QueryTarget -> QueryObject -> IO ()
+beginQuery t = glBeginQueryARB (marshalQueryTarget t) . queryID
+
+EXTENSION_ENTRY("GL_ARB_occlusion_query or OpenGL 1.5",glBeginQueryARB,GLenum -> GLuint -> IO ())
+
+endQuery :: QueryTarget -> IO ()
+endQuery = glEndQueryARB . marshalQueryTarget
+
+EXTENSION_ENTRY("GL_ARB_occlusion_query or OpenGL 1.5",glEndQueryARB,GLenum -> IO ())
+
+withQuery :: QueryTarget -> QueryObject -> GL a -> GL a
+withQuery t q x = liftIO $ bracket_ (beginQuery t q) (endQuery t) (runGL x)
+
+--------------------------------------------------------------------------------
+
+data GetQueryPName =
+     QueryCounterBits
+   | CurrentQuery
+
+marshalGetQueryPName :: GetQueryPName -> GLenum
+marshalGetQueryPName x = case x of
+   QueryCounterBits -> 0x8864
+   CurrentQuery -> 0x8865
+
+--------------------------------------------------------------------------------
+
+queryCounterBits :: QueryTarget -> GettableStateVar GLsizei
+queryCounterBits = getQueryi fromIntegral QueryCounterBits
+
+currentQuery :: QueryTarget -> GettableStateVar (Maybe QueryObject)
+currentQuery =
+   getQueryi
+      (\q -> if q == 0 then Nothing else Just (QueryObject (fromIntegral q)))
+      CurrentQuery
+
+getQueryi :: (GLint -> a) -> GetQueryPName -> QueryTarget -> GettableStateVar a
+getQueryi f p t =
+   makeGettableStateVar $
+      alloca $ \buf -> do
+         glGetQueryivARB (marshalQueryTarget t) (marshalGetQueryPName p) buf
+         peek1 f buf
+
+EXTENSION_ENTRY("GL_ARB_occlusion_query or OpenGL 1.5",glGetQueryivARB,GLenum -> GLenum -> Ptr GLint -> IO ())
+
+--------------------------------------------------------------------------------
+
+data GetQueryObjectPName =
+     QueryResult
+   | QueryResultAvailable
+
+marshalGetQueryObjectPName :: GetQueryObjectPName -> GLenum
+marshalGetQueryObjectPName x = case x of
+   QueryResult -> 0x8866
+   QueryResultAvailable -> 0x8867
+
+--------------------------------------------------------------------------------
+
+queryResult :: QueryObject -> GettableStateVar GLuint
+queryResult = getQueryObjectui id QueryResult
+
+queryResultAvailable :: QueryObject -> GettableStateVar Bool
+queryResultAvailable = getQueryObjectui unmarshalGLboolean QueryResultAvailable
+
+getQueryObjectui ::
+   (GLuint -> a) -> GetQueryObjectPName -> QueryObject -> GettableStateVar a
+getQueryObjectui f p q =
+   makeGettableStateVar $
+      alloca $ \buf -> do
+         glGetQueryObjectuivARB (queryID q) (marshalGetQueryObjectPName p) buf
+         peek1 f buf
+
+EXTENSION_ENTRY("GL_ARB_occlusion_query or OpenGL 1.5",glGetQueryObjectuivARB,GLuint -> GLenum -> Ptr GLuint -> IO ())
+
+--------------------------------------------------------------------------------
+
+blend :: StateVar Capability
+blend = makeCapability CapBlend
+
+--------------------------------------------------------------------------------
+
+data BlendEquation =
+     FuncAdd
+   | FuncSubtract
+   | FuncReverseSubtract
+   | Min
+   | Max
+   | LogicOp
+   deriving ( Eq, Ord, Show )
+
+marshalBlendEquation :: BlendEquation -> GLenum
+marshalBlendEquation x = case x of
+   FuncAdd -> 0x8006
+   FuncSubtract -> 0x800a
+   FuncReverseSubtract -> 0x800b
+   Min -> 0x8007
+   Max -> 0x8008
+   LogicOp -> 0xbf1
+
+unmarshalBlendEquation :: GLenum -> BlendEquation
+unmarshalBlendEquation x
+   | x == 0x8006 = FuncAdd
+   | x == 0x800a = FuncSubtract
+   | x == 0x800b = FuncReverseSubtract
+   | x == 0x8007 = Min
+   | x == 0x8008 = Max
+   | x == 0xbf1 = LogicOp
+   | otherwise = error ("unmarshalBlendEquation: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+blendEquation :: StateVar BlendEquation
+blendEquation =
+   makeStateVar
+      (getEnum1 unmarshalBlendEquation GetBlendEquation)
+      (glBlendEquationEXT . marshalBlendEquation)
+
+EXTENSION_ENTRY("GL_EXT_blend_minmax or GL_EXT_blend_subtract or OpenGL 1.4",glBlendEquationEXT,GLenum -> IO ())
+
+blendEquationSeparate :: StateVar (BlendEquation,BlendEquation)
+blendEquationSeparate =
+   makeStateVar
+      (liftM2 (,) (getEnum1 unmarshalBlendEquation GetBlendEquation)
+                  (getEnum1 unmarshalBlendEquation GetBlendEquationAlpha))
+      (\(funcRGB, funcAlpha) ->
+          glBlendEquationSeparate (marshalBlendEquation funcRGB)
+                                  (marshalBlendEquation funcAlpha))
+
+EXTENSION_ENTRY("GL_EXT_blend_equation_separate or OpenGL 2.0",glBlendEquationSeparate,GLenum -> GLenum -> IO ())
+
+--------------------------------------------------------------------------------
+
+blendFuncSeparate ::
+   StateVar ((BlendingFactor, BlendingFactor), (BlendingFactor, BlendingFactor))
+blendFuncSeparate =
+   makeStateVar
+      (do srcRGB   <- getEnum1 unmarshalBlendingFactor GetBlendSrcRGB
+          srcAlpha <- getEnum1 unmarshalBlendingFactor GetBlendSrcAlpha
+          dstRGB   <- getEnum1 unmarshalBlendingFactor GetBlendDstRGB
+          dstAlpha <- getEnum1 unmarshalBlendingFactor GetBlendDstAlpha
+          return ((srcRGB, srcAlpha), (dstRGB, dstAlpha)))
+      (\((srcRGB, srcAlpha), (dstRGB, dstAlpha)) ->
+         glBlendFuncSeparateEXT (marshalBlendingFactor srcRGB)
+                                (marshalBlendingFactor srcAlpha)
+                                (marshalBlendingFactor dstRGB)
+                                (marshalBlendingFactor dstAlpha))
+
+EXTENSION_ENTRY("GL_EXT_blend_func_separate or OpenGL 1.4",glBlendFuncSeparateEXT,GLenum -> GLenum -> GLenum -> GLenum -> IO ())
+
+blendFunc :: StateVar (BlendingFactor, BlendingFactor)
+blendFunc =
+   makeStateVar
+      (liftM2 (,) (getEnum1 unmarshalBlendingFactor GetBlendSrc)
+                  (getEnum1 unmarshalBlendingFactor GetBlendDst))
+      (\(s, d) ->
+         glBlendFunc (marshalBlendingFactor s) (marshalBlendingFactor d))
+
+foreign import CALLCONV unsafe "glBlendFunc" glBlendFunc ::
+   GLenum -> GLenum -> IO ()
+
+blendColor :: StateVar (Color4 GLclampf)
+blendColor =
+   makeStateVar
+      (getFloat4 Color4 GetBlendColor)
+      (\(Color4 r g b a) -> glBlendColorEXT r g b a)
+
+EXTENSION_ENTRY("GL_EXT_blend_color or OpenGL 1.4",glBlendColorEXT,GLclampf -> GLclampf -> GLclampf -> GLclampf -> IO ())
+
+--------------------------------------------------------------------------------
+
+dither :: StateVar Capability
+dither = makeCapability CapDither
+
+--------------------------------------------------------------------------------
+
+data LogicOp =
+     Clear
+   | And
+   | AndReverse
+   | Copy
+   | AndInverted
+   | Noop
+   | Xor
+   | Or
+   | Nor
+   | Equiv
+   | Invert
+   | OrReverse
+   | CopyInverted
+   | OrInverted
+   | Nand
+   | Set
+   deriving ( Eq, Ord, Show )
+
+marshalLogicOp :: LogicOp -> GLenum
+marshalLogicOp x = case x of
+   Clear -> 0x1500
+   And -> 0x1501
+   AndReverse -> 0x1502
+   Copy -> 0x1503
+   AndInverted -> 0x1504
+   Noop -> 0x1505
+   Xor -> 0x1506
+   Or -> 0x1507
+   Nor -> 0x1508
+   Equiv -> 0x1509
+   Invert -> 0x150a
+   OrReverse -> 0x150b
+   CopyInverted -> 0x150c
+   OrInverted -> 0x150d
+   Nand -> 0x150e
+   Set -> 0x150f
+
+unmarshalLogicOp :: GLenum -> LogicOp
+unmarshalLogicOp x
+   | x == 0x1500 = Clear
+   | x == 0x1501 = And
+   | x == 0x1502 = AndReverse
+   | x == 0x1503 = Copy
+   | x == 0x1504 = AndInverted
+   | x == 0x1505 = Noop
+   | x == 0x1506 = Xor
+   | x == 0x1507 = Or
+   | x == 0x1508 = Nor
+   | x == 0x1509 = Equiv
+   | x == 0x150a = Invert
+   | x == 0x150b = OrReverse
+   | x == 0x150c = CopyInverted
+   | x == 0x150d = OrInverted
+   | x == 0x150e = Nand
+   | x == 0x150f = Set
+   | otherwise = error ("unmarshalLogicOp: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+logicOp :: StateVar (Maybe LogicOp)
+logicOp =
+   makeStateVarMaybe
+      (do rgba <- getIO rgbaMode
+          return $ if rgba then CapColorLogicOp else CapIndexLogicOp)
+      (getEnum1 unmarshalLogicOp GetLogicOpMode)
+      (glLogicOp . marshalLogicOp)
+
+foreign import CALLCONV unsafe "glLogicOp" glLogicOp :: GLenum -> IO ()
diff --git a/Graphics/Rendering/OGL/GL/PixelData.hs b/Graphics/Rendering/OGL/GL/PixelData.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PixelData.hs
@@ -0,0 +1,41 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PixelData
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal helper module.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PixelData (
+   PixelData(..), withPixelData
+) where
+
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum )
+import Graphics.Rendering.OGL.GL.DataType ( DataType, marshalDataType )
+import Graphics.Rendering.OGL.GL.PixelFormat (
+   PixelFormat, marshalPixelFormat )
+
+--------------------------------------------------------------------------------
+
+data PixelData a = PixelData PixelFormat DataType (Ptr a)
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq (PixelData a)
+instance Ord (PixelData a)
+instance Show (PixelData a)
+#else
+   deriving ( Eq, Ord, Show )
+#endif
+
+withPixelData :: PixelData a -> (GLenum -> GLenum -> Ptr a -> b) -> b
+withPixelData (PixelData pixelFormat dataType ptr) f =
+   f (marshalPixelFormat pixelFormat) (marshalDataType dataType) ptr
diff --git a/Graphics/Rendering/OGL/GL/PixelFormat.hs b/Graphics/Rendering/OGL/GL/PixelFormat.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PixelFormat.hs
@@ -0,0 +1,99 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PixelFormat
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for (un-)marshaling PixelFormat.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PixelFormat (
+   PixelFormat(..), marshalPixelFormat, unmarshalPixelFormat
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum )
+
+--------------------------------------------------------------------------------
+
+data PixelFormat =
+     ColorIndex
+   | StencilIndex
+   | DepthComponent
+   | Red
+   | Green
+   | Blue
+   | Alpha
+   | RGB
+   | RGBA
+   | Luminance
+   | LuminanceAlpha
+   | ABGR
+   | BGR
+   | BGRA
+   | CMYK
+   | CMYKA
+   | FourTwoTwo
+   | FourTwoTwoRev
+   | FourTwoTwoAverage
+   | FourTwoTwoRevAverage
+   | YCBCR422
+   | DepthStencil
+   deriving ( Eq, Ord, Show )
+
+marshalPixelFormat :: PixelFormat -> GLenum
+marshalPixelFormat x = case x of
+   ColorIndex -> 0x1900
+   StencilIndex -> 0x1901
+   DepthComponent -> 0x1902
+   Red -> 0x1903
+   Green -> 0x1904
+   Blue -> 0x1905
+   Alpha -> 0x1906
+   RGB -> 0x1907
+   RGBA -> 0x1908
+   Luminance -> 0x1909
+   LuminanceAlpha -> 0x190a
+   ABGR -> 0x8000
+   BGR -> 0x80E0
+   BGRA -> 0x80E1
+   CMYK -> 0x800C
+   CMYKA -> 0x800D
+   FourTwoTwo -> 0x80CC
+   FourTwoTwoRev -> 0x80CD
+   FourTwoTwoAverage -> 0x80CE
+   FourTwoTwoRevAverage -> 0x80CF
+   YCBCR422 -> 0x85B9
+   DepthStencil -> 0x84f9
+
+unmarshalPixelFormat :: GLenum -> PixelFormat
+unmarshalPixelFormat x
+   | x == 0x1900 = ColorIndex
+   | x == 0x1901 = StencilIndex
+   | x == 0x1902 = DepthComponent
+   | x == 0x1903 = Red
+   | x == 0x1904 = Green
+   | x == 0x1905 = Blue
+   | x == 0x1906 = Alpha
+   | x == 0x1907 = RGB
+   | x == 0x1908 = RGBA
+   | x == 0x1909 = Luminance
+   | x == 0x190a = LuminanceAlpha
+   | x == 0x8000 = ABGR
+   | x == 0x80E0 = BGR
+   | x == 0x80E1 = BGRA
+   | x == 0x800C = CMYK
+   | x == 0x800D = CMYKA
+   | x == 0x80CC = FourTwoTwo
+   | x == 0x80CD = FourTwoTwoRev
+   | x == 0x80CE = FourTwoTwoAverage
+   | x == 0x80CF = FourTwoTwoRevAverage
+   | x == 0x85B9 = YCBCR422
+   | x == 0x84f9 = DepthStencil
+   | otherwise = error ("unmarshalPixelFormat: illegal value " ++ show x)
diff --git a/Graphics/Rendering/OGL/GL/PixelRectangles.hs b/Graphics/Rendering/OGL/GL/PixelRectangles.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PixelRectangles.hs
@@ -0,0 +1,34 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PixelRectangles
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.6 (Pixel Rectangles) of the OpenGL 2.1
+-- specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PixelRectangles (
+   module Graphics.Rendering.OGL.GL.PixelRectangles.PixelStorage,
+   module Graphics.Rendering.OGL.GL.PixelRectangles.PixelTransfer,
+   module Graphics.Rendering.OGL.GL.PixelRectangles.PixelMap,
+   module Graphics.Rendering.OGL.GL.PixelRectangles.ColorTable,
+   module Graphics.Rendering.OGL.GL.PixelRectangles.Convolution,
+   module Graphics.Rendering.OGL.GL.PixelRectangles.Histogram,
+   module Graphics.Rendering.OGL.GL.PixelRectangles.Minmax,
+   module Graphics.Rendering.OGL.GL.PixelRectangles.Rasterization
+) where
+
+import Graphics.Rendering.OGL.GL.PixelRectangles.PixelStorage
+import Graphics.Rendering.OGL.GL.PixelRectangles.PixelTransfer
+import Graphics.Rendering.OGL.GL.PixelRectangles.PixelMap
+import Graphics.Rendering.OGL.GL.PixelRectangles.ColorTable
+import Graphics.Rendering.OGL.GL.PixelRectangles.Convolution
+import Graphics.Rendering.OGL.GL.PixelRectangles.Histogram
+import Graphics.Rendering.OGL.GL.PixelRectangles.Minmax
+import Graphics.Rendering.OGL.GL.PixelRectangles.Rasterization
diff --git a/Graphics/Rendering/OGL/GL/PixelRectangles/ColorTable.hs b/Graphics/Rendering/OGL/GL/PixelRectangles/ColorTable.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PixelRectangles/ColorTable.hs
@@ -0,0 +1,280 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PixelRectangles.ColorTable
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to a part of section 3.6.1 (Pixel Storage Modes) of
+-- the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PixelRectangles.ColorTable (
+   ColorTableStage(..), colorTableStage,
+   Proxy(..), ColorTable(..), PixelInternalFormat(..),
+   colorTable, getColorTable, copyColorTable, colorSubTable, copyColorSubTable,
+   colorTableScale, colorTableBias, colorTableFormat, colorTableWidth,
+   colorTableRGBASizes, colorTableLuminanceSize, colorTableIntesitySize,
+) where
+
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Marshal.Utils ( with )
+import Foreign.Ptr ( Ptr )
+import Foreign.Storable ( Storable(..) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapColorTable,CapPostConvolutionColorTable,
+             CapPostColorMatrixColorTable,CapTextureColorTable),
+   makeCapability )
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLenum, GLint, GLsizei, GLfloat, Capability )
+import Graphics.Rendering.OGL.GL.CoordTrans ( Position(..) )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.PeekPoke ( peek1 )
+import Graphics.Rendering.OGL.GL.PixelRectangles.Rasterization (
+    PixelData(..) )
+import Graphics.Rendering.OGL.GL.PixelData ( withPixelData )
+import Graphics.Rendering.OGL.GL.Texturing.PixelInternalFormat (
+   PixelInternalFormat(..), marshalPixelInternalFormat',
+   unmarshalPixelInternalFormat )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.VertexSpec ( Color4(..) )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal (
+   recordInvalidEnum )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+
+--------------------------------------------------------------------------------
+
+data ColorTableStage =
+     ColorTableStage
+   | PostConvolutionColorTableStage
+   | PostColorMatrixColorTableStage
+   | TextureColorTableStage
+   deriving ( Eq, Ord, Show )
+
+colorTableStageToColorTable :: ColorTableStage -> ColorTable
+colorTableStageToColorTable x = case x of
+   ColorTableStage -> ColorTable
+   PostConvolutionColorTableStage -> PostConvolutionColorTable
+   PostColorMatrixColorTableStage -> PostColorMatrixColorTable
+   TextureColorTableStage -> TextureColorTable
+
+colorTableStageToEnableCap :: ColorTableStage -> EnableCap
+colorTableStageToEnableCap x = case x of
+   ColorTableStage -> CapColorTable
+   PostConvolutionColorTableStage -> CapPostConvolutionColorTable
+   PostColorMatrixColorTableStage -> CapPostColorMatrixColorTable
+   TextureColorTableStage -> CapTextureColorTable
+
+--------------------------------------------------------------------------------
+
+colorTableStage :: ColorTableStage -> StateVar Capability
+colorTableStage = makeCapability . colorTableStageToEnableCap
+
+--------------------------------------------------------------------------------
+
+data ColorTable =
+     ColorTable
+   | PostConvolutionColorTable
+   | PostColorMatrixColorTable
+   | Texture1DColorTable
+   | Texture2DColorTable
+   | Texture3DColorTable
+   | TextureCubeMapColorTable
+   | TextureColorTable
+   | SharedTexturePalette
+   deriving ( Eq, Ord, Show )
+
+marshalColorTable :: ColorTable -> GLenum
+marshalColorTable x = case x of
+   ColorTable -> 0x80d0
+   PostConvolutionColorTable -> 0x80d1
+   PostColorMatrixColorTable -> 0x80d2
+   Texture1DColorTable -> 0xde0
+   Texture2DColorTable -> 0xde1
+   Texture3DColorTable -> 0x806f
+   TextureCubeMapColorTable -> 0x8513
+   TextureColorTable -> 0x80bc
+   SharedTexturePalette -> 0x81fb
+
+--------------------------------------------------------------------------------
+
+data Proxy =
+     NoProxy
+   | Proxy
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+marshalProxyColorTable :: Proxy -> ColorTable -> Maybe GLenum
+marshalProxyColorTable NoProxy x = Just (marshalColorTable x)
+marshalProxyColorTable Proxy   x = case x of
+   ColorTable -> Just 0x80d3
+   PostConvolutionColorTable -> Just 0x80d4
+   PostColorMatrixColorTable -> Just 0x80d5
+   Texture1DColorTable -> Just 0x8063
+   Texture2DColorTable -> Just 0x8064
+   Texture3DColorTable -> Just 0x8070
+   TextureCubeMapColorTable -> Just 0x851b
+   TextureColorTable -> Just 0x80bd
+   SharedTexturePalette -> Nothing
+
+--------------------------------------------------------------------------------
+
+colorTable ::
+   Proxy -> ColorTable -> PixelInternalFormat -> GLsizei -> PixelData a -> GL ()
+colorTable proxy ct int w pd = liftIO $ 
+   maybe recordInvalidEnum
+         (\target -> withPixelData pd $
+            glColorTable target (marshalPixelInternalFormat' int) w)
+         (marshalProxyColorTable proxy ct)
+
+EXTENSION_ENTRY("GL_ARB_imaging",glColorTable,GLenum -> GLenum -> GLsizei -> GLenum -> GLenum -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+getColorTable :: ColorTable -> PixelData a -> GL ()
+getColorTable ct pd = liftIO . 
+   withPixelData pd $ glGetColorTable (marshalColorTable ct)
+
+EXTENSION_ENTRY("GL_ARB_imaging",glGetColorTable,GLenum -> GLenum -> GLenum -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+copyColorTable :: ColorTable -> PixelInternalFormat -> Position -> GLsizei -> GL ()
+copyColorTable ct int (Position x y) = liftIO . 
+   glCopyColorTable (marshalColorTable ct) (marshalPixelInternalFormat' int) x y
+
+EXTENSION_ENTRY("GL_ARB_imaging",glCopyColorTable,GLenum -> GLenum -> GLint -> GLint -> GLsizei -> IO ())
+
+--------------------------------------------------------------------------------
+
+colorSubTable :: ColorTable -> GLsizei -> GLsizei -> PixelData a -> GL ()
+colorSubTable ct start count pd = liftIO .
+   withPixelData pd $ glColorSubTable (marshalColorTable ct) start count
+
+EXTENSION_ENTRY("GL_ARB_imaging",glColorSubTable,GLenum -> GLsizei -> GLsizei -> GLenum -> GLenum -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+copyColorSubTable :: ColorTable -> GLsizei -> Position -> GLsizei -> GL ()
+copyColorSubTable ct start (Position x y) = liftIO . 
+   glCopyColorSubTable (marshalColorTable ct) start x y
+
+EXTENSION_ENTRY("GL_ARB_imaging",glCopyColorSubTable,GLenum -> GLsizei -> GLint -> GLint -> GLsizei -> IO ())
+
+--------------------------------------------------------------------------------
+
+data ColorTablePName =
+     ColorTableScale
+   | ColorTableBias
+   | ColorTableFormat
+   | ColorTableWidth
+   | ColorTableRedSize
+   | ColorTableGreenSize
+   | ColorTableBlueSize
+   | ColorTableAlphaSize
+   | ColorTableLuminanceSize
+   | ColorTableIntensitySize
+
+marshalColorTablePName :: ColorTablePName -> GLenum
+marshalColorTablePName x = case x of
+   ColorTableScale -> 0x80d6
+   ColorTableBias -> 0x80d7
+   ColorTableFormat -> 0x80d8
+   ColorTableWidth -> 0x80d9
+   ColorTableRedSize -> 0x80da
+   ColorTableGreenSize -> 0x80db
+   ColorTableBlueSize -> 0x80dc
+   ColorTableAlphaSize -> 0x80dd
+   ColorTableLuminanceSize -> 0x80de
+   ColorTableIntensitySize -> 0x80df
+
+--------------------------------------------------------------------------------
+
+colorTableScale :: ColorTableStage -> StateVar (Color4 GLfloat)
+colorTableScale = colorTableScaleBias ColorTableScale
+
+colorTableBias :: ColorTableStage -> StateVar (Color4 GLfloat)
+colorTableBias = colorTableScaleBias ColorTableBias
+
+colorTableScaleBias ::
+   ColorTablePName -> ColorTableStage -> StateVar (Color4 GLfloat)
+colorTableScaleBias p s =
+   makeStateVar (getColorTableParameterC4f ct p) (colorTableParameterC4f ct p)
+   where ct = colorTableStageToColorTable s
+
+getColorTableParameterC4f ::
+   ColorTable -> ColorTablePName -> IO (Color4 GLfloat) 
+getColorTableParameterC4f ct p =
+   alloca $ \buf -> do
+      glGetColorTableParameterfv
+         (marshalColorTable ct)
+         (marshalColorTablePName p)
+         buf
+      peek buf
+
+EXTENSION_ENTRY("GL_ARB_imaging",glGetColorTableParameterfv,GLenum -> GLenum -> Ptr (Color4 GLfloat) -> IO ())
+
+colorTableParameterC4f ::
+   ColorTable -> ColorTablePName -> Color4 GLfloat -> IO ()
+colorTableParameterC4f ct p c =
+   with c $
+      glColorTableParameterfv (marshalColorTable ct) (marshalColorTablePName p)
+
+EXTENSION_ENTRY("GL_ARB_imaging",glColorTableParameterfv,GLenum -> GLenum -> Ptr (Color4 GLfloat) -> IO ())
+
+--------------------------------------------------------------------------------
+
+colorTableFormat :: ColorTable -> GettableStateVar PixelInternalFormat
+colorTableFormat ct =
+   makeGettableStateVar $
+      getColorTableParameteri unmarshalPixelInternalFormat ct ColorTableFormat
+
+getColorTableParameteri :: (GLint -> a) -> ColorTable -> ColorTablePName -> IO a
+getColorTableParameteri f ct p =
+   alloca $ \buf -> do
+      glGetColorTableParameteriv
+         (marshalColorTable ct)
+         (marshalColorTablePName p)
+         buf
+      peek1 f buf
+
+EXTENSION_ENTRY("GL_ARB_imaging",glGetColorTableParameteriv,GLenum -> GLenum -> Ptr GLint -> IO ())
+
+--------------------------------------------------------------------------------
+
+colorTableWidth :: ColorTable -> GettableStateVar GLsizei
+colorTableWidth ct =
+   makeGettableStateVar $
+      getColorTableParameteri fromIntegral ct ColorTableWidth
+
+--------------------------------------------------------------------------------
+
+colorTableRGBASizes :: ColorTable -> GettableStateVar (Color4 GLsizei)
+colorTableRGBASizes ct =
+   makeGettableStateVar $ do
+      r <- getColorTableParameteri fromIntegral ct ColorTableRedSize
+      g <- getColorTableParameteri fromIntegral ct ColorTableGreenSize
+      b <- getColorTableParameteri fromIntegral ct ColorTableBlueSize
+      a <- getColorTableParameteri fromIntegral ct ColorTableAlphaSize
+      return $ Color4 r g b a
+
+colorTableLuminanceSize :: ColorTable -> GettableStateVar GLsizei
+colorTableLuminanceSize ct =
+   makeGettableStateVar $
+      getColorTableParameteri fromIntegral ct ColorTableLuminanceSize
+
+colorTableIntesitySize :: ColorTable -> GettableStateVar GLsizei
+colorTableIntesitySize ct =
+   makeGettableStateVar $
+      getColorTableParameteri fromIntegral ct ColorTableIntensitySize
diff --git a/Graphics/Rendering/OGL/GL/PixelRectangles/Convolution.hs b/Graphics/Rendering/OGL/GL/PixelRectangles/Convolution.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PixelRectangles/Convolution.hs
@@ -0,0 +1,319 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PixelRectangles.Convolution
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to a part of section 3.6.1 (Pixel Storage Modes) of
+-- the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PixelRectangles.Convolution (
+   ConvolutionTarget(..), convolution,
+   convolutionFilter1D, getConvolutionFilter1D,
+   convolutionFilter2D, getConvolutionFilter2D,
+   separableFilter2D, getSeparableFilter2D,
+   copyConvolutionFilter1D, copyConvolutionFilter2D,
+   convolutionWidth, convolutionHeight,
+   maxConvolutionWidth, maxConvolutionHeight,
+   ConvolutionBorderMode(..), convolutionBorderMode,
+   convolutionFilterScale, convolutionFilterBias,
+) where
+
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Marshal.Utils ( with )
+import Foreign.Ptr ( Ptr, nullPtr )
+import Foreign.Storable ( Storable(..) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapConvolution1D, CapConvolution2D,CapSeparable2D),
+   makeCapability )
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLenum, GLint, GLsizei, GLfloat, Capability )
+import Graphics.Rendering.OGL.GL.CoordTrans ( Position(..), Size(..) )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.PeekPoke ( peek1 )
+import Graphics.Rendering.OGL.GL.PixelRectangles.ColorTable (
+   PixelInternalFormat )
+import Graphics.Rendering.OGL.GL.PixelRectangles.Rasterization (
+    PixelData(..) )
+import Graphics.Rendering.OGL.GL.PixelData ( withPixelData )
+import Graphics.Rendering.OGL.GL.Texturing.PixelInternalFormat (
+   marshalPixelInternalFormat' )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.VertexSpec ( Color4(..) )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal (
+   recordInvalidValue )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+
+--------------------------------------------------------------------------------
+
+data ConvolutionTarget =
+     Convolution1D
+   | Convolution2D
+   | Separable2D
+   deriving ( Eq, Ord, Show )
+
+marshalConvolutionTarget :: ConvolutionTarget -> GLenum
+marshalConvolutionTarget x = case x of
+   Convolution1D -> 0x8010
+   Convolution2D -> 0x8011
+   Separable2D -> 0x8012
+
+convolutionTargetToEnableCap :: ConvolutionTarget -> EnableCap
+convolutionTargetToEnableCap x = case x of
+   Convolution1D -> CapConvolution1D
+   Convolution2D -> CapConvolution2D
+   Separable2D -> CapSeparable2D
+
+--------------------------------------------------------------------------------
+
+convolution :: ConvolutionTarget -> StateVar Capability
+convolution = makeCapability . convolutionTargetToEnableCap
+
+--------------------------------------------------------------------------------
+
+convolutionFilter1D :: PixelInternalFormat -> GLsizei -> PixelData a -> GL ()
+convolutionFilter1D int w pd = liftIO . 
+   withPixelData pd $
+      glConvolutionFilter1D
+         (marshalConvolutionTarget Convolution1D)
+         (marshalPixelInternalFormat' int) w
+
+EXTENSION_ENTRY("GL_ARB_imaging",glConvolutionFilter1D,GLenum -> GLenum -> GLsizei -> GLenum -> GLenum -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+getConvolutionFilter1D :: PixelData a -> GL ()
+getConvolutionFilter1D = liftIO . getConvolutionFilter Convolution1D
+
+getConvolutionFilter :: ConvolutionTarget -> PixelData a -> IO ()
+getConvolutionFilter t pd = 
+   withPixelData pd $ glGetConvolutionFilter (marshalConvolutionTarget t)
+
+EXTENSION_ENTRY("GL_ARB_imaging",glGetConvolutionFilter,GLenum -> GLenum -> GLenum -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+convolutionFilter2D :: PixelInternalFormat -> Size -> PixelData a -> GL ()
+convolutionFilter2D int (Size w h) pd = liftIO . 
+   withPixelData pd $
+      glConvolutionFilter2D
+         (marshalConvolutionTarget Convolution2D)
+         (marshalPixelInternalFormat' int) w h
+
+EXTENSION_ENTRY("GL_ARB_imaging",glConvolutionFilter2D,GLenum -> GLenum -> GLsizei -> GLsizei -> GLenum -> GLenum -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+getConvolutionFilter2D :: PixelData a -> GL ()
+getConvolutionFilter2D = liftIO . getConvolutionFilter Convolution2D
+
+--------------------------------------------------------------------------------
+
+separableFilter2D ::
+   PixelInternalFormat -> Size -> PixelData a -> PixelData a -> GL ()
+separableFilter2D int (Size w h) pdRow pdCol = liftIO . 
+   withPixelData pdRow $ \f1 d1 p1 ->
+      withPixelData pdCol $ \f2 d2 p2 ->
+         if f1 == f2 && d1 == d2
+            then glSeparableFilter2D
+                    (marshalConvolutionTarget Separable2D)
+                    (marshalPixelInternalFormat' int) w h f1 d1 p1 p2
+            else recordInvalidValue
+
+EXTENSION_ENTRY("GL_ARB_imaging",glSeparableFilter2D,GLenum -> GLenum -> GLsizei -> GLsizei -> GLenum -> GLenum -> Ptr a -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+getSeparableFilter2D :: PixelData a -> PixelData a -> GL ()
+getSeparableFilter2D pdRow pdCol = liftIO . 
+   withPixelData pdRow $ \f1 d1 p1 ->
+      withPixelData pdCol $ \f2 d2 p2 ->
+         if f1 == f2 && d1 == d2
+            then glGetSeparableFilter
+                    (marshalConvolutionTarget Separable2D) f1 d1 p1 p2 nullPtr
+            else recordInvalidValue
+
+EXTENSION_ENTRY("GL_ARB_imaging",glGetSeparableFilter,GLenum -> GLenum -> GLenum -> Ptr a -> Ptr a -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+copyConvolutionFilter1D :: PixelInternalFormat -> Position -> GLsizei -> GL ()
+copyConvolutionFilter1D int (Position x y) = liftIO .
+   glCopyConvolutionFilter1D
+      (marshalConvolutionTarget Convolution1D) (marshalPixelInternalFormat' int)
+      x y
+
+EXTENSION_ENTRY("GL_ARB_imaging",glCopyConvolutionFilter1D,GLenum -> GLenum -> GLint -> GLint -> GLsizei -> IO ())
+
+--------------------------------------------------------------------------------
+
+copyConvolutionFilter2D :: PixelInternalFormat -> Position -> Size -> GL ()
+copyConvolutionFilter2D int (Position x y) (Size w h) = liftIO $
+   glCopyConvolutionFilter2D
+      (marshalConvolutionTarget Convolution2D) (marshalPixelInternalFormat' int)
+      x y w h
+
+EXTENSION_ENTRY("GL_ARB_imaging",glCopyConvolutionFilter2D,GLenum -> GLenum -> GLint -> GLint -> GLsizei -> GLsizei -> IO ())
+
+--------------------------------------------------------------------------------
+
+data ConvolutionParameter =
+     ConvolutionBorderColor
+   | ConvolutionBorderMode
+   | ConvolutionFilterScale
+   | ConvolutionFilterBias
+   | ConvolutionFormat
+   | ConvolutionWidth
+   | ConvolutionHeight
+   | MaxConvolutionWidth
+   | MaxConvolutionHeight
+   deriving ( Eq, Ord, Show )
+
+marshalConvolutionParameter :: ConvolutionParameter -> GLenum
+marshalConvolutionParameter x = case x of
+   ConvolutionBorderColor -> 0x8154
+   ConvolutionBorderMode -> 0x8013
+   ConvolutionFilterScale -> 0x8014
+   ConvolutionFilterBias -> 0x8015
+   ConvolutionFormat -> 0x8017
+   ConvolutionWidth -> 0x8018
+   ConvolutionHeight -> 0x8019
+   MaxConvolutionWidth -> 0x801a
+   MaxConvolutionHeight -> 0x801b
+
+--------------------------------------------------------------------------------
+
+convolutionWidth :: ConvolutionTarget -> GettableStateVar GLsizei
+convolutionWidth t = convolutionParameteri t ConvolutionWidth
+
+convolutionHeight :: ConvolutionTarget -> GettableStateVar GLsizei
+convolutionHeight t = convolutionParameteri t ConvolutionHeight
+
+maxConvolutionWidth :: ConvolutionTarget -> GettableStateVar GLsizei
+maxConvolutionWidth t = convolutionParameteri t MaxConvolutionWidth
+
+maxConvolutionHeight :: ConvolutionTarget -> GettableStateVar GLsizei
+maxConvolutionHeight t = convolutionParameteri t MaxConvolutionHeight
+
+convolutionParameteri ::
+   ConvolutionTarget -> ConvolutionParameter -> GettableStateVar GLsizei
+convolutionParameteri t p =
+   makeGettableStateVar (getConvolutionParameteri fromIntegral t p)
+
+getConvolutionParameteri ::
+   (GLint -> a) -> ConvolutionTarget -> ConvolutionParameter -> IO a
+getConvolutionParameteri f t p =
+   alloca $ \buf -> do
+      glGetConvolutionParameteriv
+         (marshalConvolutionTarget t) (marshalConvolutionParameter p) buf
+      peek1 f buf
+
+EXTENSION_ENTRY("GL_ARB_imaging",glGetConvolutionParameteriv,GLenum -> GLenum -> Ptr GLint -> IO ())
+
+--------------------------------------------------------------------------------
+
+data ConvolutionBorderMode' =
+     Reduce'
+   | ConstantBorder'
+   | ReplicateBorder'
+
+marshalConvolutionBorderMode' :: ConvolutionBorderMode' -> GLint
+marshalConvolutionBorderMode' x = case x of
+   Reduce' -> 0x8016
+   ConstantBorder' -> 0x8151
+   ReplicateBorder' -> 0x8153
+
+unmarshalConvolutionBorderMode' :: GLint -> ConvolutionBorderMode'
+unmarshalConvolutionBorderMode' x
+   | x == 0x8016 = Reduce'
+   | x == 0x8151 = ConstantBorder'
+   | x == 0x8153 = ReplicateBorder'
+   | otherwise = error ("unmarshalConvolutionBorderMode': illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+data ConvolutionBorderMode =
+     Reduce
+   | ConstantBorder (Color4 GLfloat)
+   | ReplicateBorder
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+convolutionBorderMode :: ConvolutionTarget -> StateVar ConvolutionBorderMode
+convolutionBorderMode t =
+   makeStateVar (getConvolutionBorderMode t) (setConvolutionBorderMode t)
+
+getConvolutionBorderMode :: ConvolutionTarget -> IO ConvolutionBorderMode
+getConvolutionBorderMode t = do
+   mode <- getConvolutionParameteri
+              unmarshalConvolutionBorderMode' t ConvolutionBorderMode
+   case mode of
+      Reduce' -> return Reduce
+      ConstantBorder' -> do
+         c <- getConvolutionParameterC4f t ConvolutionBorderColor
+         return $ ConstantBorder c
+      ReplicateBorder' -> return ReplicateBorder
+
+setConvolutionBorderMode :: ConvolutionTarget -> ConvolutionBorderMode -> IO ()
+setConvolutionBorderMode t mode = do
+   let setBM = setConvolutionParameteri
+                  marshalConvolutionBorderMode' t ConvolutionBorderMode
+   case mode of
+      Reduce -> setBM Reduce'
+      ConstantBorder c -> do
+         setBM ConstantBorder'
+         convolutionParameterC4f t ConvolutionBorderColor c
+      ReplicateBorder -> setBM ReplicateBorder'
+
+setConvolutionParameteri ::
+   (a -> GLint) -> ConvolutionTarget -> ConvolutionParameter -> a -> IO ()
+setConvolutionParameteri f t p x =
+   glConvolutionParameteri
+      (marshalConvolutionTarget t) (marshalConvolutionParameter p) (f x)
+
+EXTENSION_ENTRY("GL_ARB_imaging",glConvolutionParameteri,GLenum -> GLenum -> GLint -> IO ())
+
+--------------------------------------------------------------------------------
+
+convolutionFilterScale :: ConvolutionTarget -> StateVar (Color4 GLfloat)
+convolutionFilterScale = convolutionC4f ConvolutionFilterScale
+
+convolutionFilterBias :: ConvolutionTarget -> StateVar (Color4 GLfloat)
+convolutionFilterBias = convolutionC4f ConvolutionFilterBias
+
+convolutionC4f ::
+   ConvolutionParameter -> ConvolutionTarget -> StateVar (Color4 GLfloat)
+convolutionC4f p t =
+   makeStateVar (getConvolutionParameterC4f t p) (convolutionParameterC4f t p)
+
+getConvolutionParameterC4f ::
+   ConvolutionTarget -> ConvolutionParameter -> IO (Color4 GLfloat)
+getConvolutionParameterC4f t p =
+   alloca $ \buf -> do
+      glGetConvolutionParameterfv
+         (marshalConvolutionTarget t) (marshalConvolutionParameter p) buf
+      peek buf
+
+EXTENSION_ENTRY("GL_ARB_imaging",glGetConvolutionParameterfv,GLenum -> GLenum -> Ptr (Color4 GLfloat) -> IO ())
+
+convolutionParameterC4f ::
+   ConvolutionTarget -> ConvolutionParameter -> Color4 GLfloat -> IO ()
+convolutionParameterC4f t p c =
+   with c $
+      glConvolutionParameterfv
+         (marshalConvolutionTarget t) (marshalConvolutionParameter p)
+
+EXTENSION_ENTRY("GL_ARB_imaging",glConvolutionParameterfv,GLenum -> GLenum -> Ptr (Color4 GLfloat) -> IO ())
diff --git a/Graphics/Rendering/OGL/GL/PixelRectangles/Histogram.hs b/Graphics/Rendering/OGL/GL/PixelRectangles/Histogram.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PixelRectangles/Histogram.hs
@@ -0,0 +1,158 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PixelRectangles.Histogram
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to a part of section 3.6.1 (Pixel Storage Modes) of
+-- the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PixelRectangles.Histogram (
+   Sink(..), histogram, Reset(..), getHistogram, resetHistogram,
+   histogramRGBASizes, histogramLuminanceSize
+) where
+
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapHistogram), makeStateVarMaybe )
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLboolean, GLenum, GLint, GLsizei )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.PeekPoke ( peek1 )
+import Graphics.Rendering.OGL.GL.PixelRectangles.Rasterization (
+    PixelData(..) )
+import Graphics.Rendering.OGL.GL.PixelRectangles.ColorTable (
+   PixelInternalFormat )
+import Graphics.Rendering.OGL.GL.PixelData ( withPixelData )
+import Graphics.Rendering.OGL.GL.Texturing.PixelInternalFormat (
+   marshalPixelInternalFormat', unmarshalPixelInternalFormat )
+import Graphics.Rendering.OGL.GL.PixelRectangles.ColorTable ( Proxy(..) )
+import Graphics.Rendering.OGL.GL.PixelRectangles.Sink (
+   Sink(..), marshalSink, unmarshalSink )
+import Graphics.Rendering.OGL.GL.PixelRectangles.Reset (
+   Reset(..), marshalReset )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar, StateVar )
+import Graphics.Rendering.OGL.GL.VertexSpec ( Color4(..) )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+
+--------------------------------------------------------------------------------
+
+data HistogramTarget =
+     Histogram
+   | ProxyHistogram
+
+marshalHistogramTarget :: HistogramTarget -> GLenum
+marshalHistogramTarget x = case x of
+   Histogram -> 0x8024
+   ProxyHistogram -> 0x8025
+
+proxyToHistogramTarget :: Proxy -> HistogramTarget
+proxyToHistogramTarget x = case x of
+   NoProxy -> Histogram
+   Proxy -> ProxyHistogram
+
+--------------------------------------------------------------------------------
+
+histogram :: Proxy -> StateVar (Maybe (GLsizei, PixelInternalFormat, Sink))
+histogram proxy =
+   makeStateVarMaybe
+      (return CapHistogram) (getHistogram' proxy) (setHistogram proxy)
+
+getHistogram' :: Proxy -> IO (GLsizei, PixelInternalFormat, Sink)
+getHistogram' proxy = do
+   w <- getHistogramParameteri fromIntegral proxy HistogramWidth
+   f <- getHistogramParameteri unmarshalPixelInternalFormat proxy HistogramFormat
+   s <- getHistogramParameteri unmarshalSink proxy HistogramSink
+   return (w, f, s)
+
+getHistogramParameteri ::
+   (GLint -> a) -> Proxy -> GetHistogramParameterPName -> IO a
+getHistogramParameteri f proxy p =
+   alloca $ \buf -> do
+      glGetHistogramParameteriv
+         (marshalHistogramTarget (proxyToHistogramTarget proxy))
+         (marshalGetHistogramParameterPName p)
+         buf
+      peek1 f buf
+
+EXTENSION_ENTRY("GL_ARB_imaging",glGetHistogramParameteriv,GLenum -> GLenum -> Ptr GLint -> IO ())
+
+setHistogram :: Proxy -> (GLsizei, PixelInternalFormat, Sink) -> IO ()
+setHistogram proxy (w, int, sink) =
+   glHistogram
+      (marshalHistogramTarget (proxyToHistogramTarget proxy))
+      w
+      (marshalPixelInternalFormat' int)
+      (marshalSink sink)
+         
+EXTENSION_ENTRY("GL_ARB_imaging",glHistogram,GLenum -> GLsizei -> GLenum -> GLboolean -> IO ())
+
+--------------------------------------------------------------------------------
+
+getHistogram :: Reset -> PixelData a -> GL ()
+getHistogram reset pd = liftIO . 
+   withPixelData pd $
+      glGetHistogram
+         (marshalHistogramTarget Histogram)
+         (marshalReset reset)
+
+EXTENSION_ENTRY("GL_ARB_imaging",glGetHistogram,GLenum -> GLboolean -> GLenum -> GLenum -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+resetHistogram :: GL ()
+resetHistogram = glResetHistogram (marshalHistogramTarget Histogram)
+
+EXTENSION_ENTRY("GL_ARB_imaging",glResetHistogram,GLenum -> GL ())
+
+--------------------------------------------------------------------------------
+
+data GetHistogramParameterPName =
+     HistogramWidth
+   | HistogramFormat
+   | HistogramRedSize
+   | HistogramGreenSize
+   | HistogramBlueSize
+   | HistogramAlphaSize
+   | HistogramLuminanceSize
+   | HistogramSink
+
+marshalGetHistogramParameterPName :: GetHistogramParameterPName -> GLenum
+marshalGetHistogramParameterPName x = case x of
+   HistogramWidth -> 0x8026
+   HistogramFormat -> 0x8027
+   HistogramRedSize -> 0x8028
+   HistogramGreenSize -> 0x8029
+   HistogramBlueSize -> 0x802a
+   HistogramAlphaSize -> 0x802b
+   HistogramLuminanceSize -> 0x802c
+   HistogramSink -> 0x802d
+
+--------------------------------------------------------------------------------
+
+histogramRGBASizes :: Proxy -> GettableStateVar (Color4 GLsizei)
+histogramRGBASizes proxy =
+   makeGettableStateVar $ do
+      r <- getHistogramParameteri fromIntegral proxy HistogramRedSize
+      g <- getHistogramParameteri fromIntegral proxy HistogramGreenSize
+      b <- getHistogramParameteri fromIntegral proxy HistogramBlueSize
+      a <- getHistogramParameteri fromIntegral proxy HistogramAlphaSize
+      return $ Color4 r g b a
+
+histogramLuminanceSize :: Proxy -> GettableStateVar GLsizei
+histogramLuminanceSize proxy =
+   makeGettableStateVar $
+      getHistogramParameteri id proxy HistogramLuminanceSize
diff --git a/Graphics/Rendering/OGL/GL/PixelRectangles/Minmax.hs b/Graphics/Rendering/OGL/GL/PixelRectangles/Minmax.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PixelRectangles/Minmax.hs
@@ -0,0 +1,115 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PixelRectangles.Minmax
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to a part of section 3.6.1 (Pixel Storage Modes) of
+-- the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PixelRectangles.Minmax (
+   minmax, getMinmax, resetMinmax
+) where
+
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapMinmax), makeStateVarMaybe )
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLboolean, GLenum, GLint )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.PeekPoke ( peek1 )
+import Graphics.Rendering.OGL.GL.PixelRectangles.ColorTable (
+   PixelInternalFormat )
+import Graphics.Rendering.OGL.GL.PixelRectangles.Rasterization (
+    PixelData(..) )
+import Graphics.Rendering.OGL.GL.PixelData ( withPixelData )
+import Graphics.Rendering.OGL.GL.Texturing.PixelInternalFormat (
+   marshalPixelInternalFormat', unmarshalPixelInternalFormat )
+import Graphics.Rendering.OGL.GL.PixelRectangles.Histogram (
+   Reset(..), Sink )
+import Graphics.Rendering.OGL.GL.PixelRectangles.Reset (
+   marshalReset )
+import Graphics.Rendering.OGL.GL.PixelRectangles.Sink (
+   marshalSink, unmarshalSink )
+import Graphics.Rendering.OGL.GL.StateVar ( StateVar )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+
+--------------------------------------------------------------------------------
+
+data MinmaxTarget =
+     Minmax
+
+marshalMinmaxTarget :: MinmaxTarget -> GLenum
+marshalMinmaxTarget x = case x of
+   Minmax -> 0x802e
+
+--------------------------------------------------------------------------------
+
+minmax :: StateVar (Maybe (PixelInternalFormat, Sink))
+minmax = makeStateVarMaybe (return CapMinmax) getMinmax' setMinmax
+
+getMinmax' :: IO (PixelInternalFormat, Sink)
+getMinmax' = do
+   f <- getMinmaxParameteri unmarshalPixelInternalFormat MinmaxFormat
+   s <- getMinmaxParameteri unmarshalSink MinmaxSink
+   return (f, s)
+
+setMinmax :: (PixelInternalFormat, Sink) -> IO ()
+setMinmax (int, sink) =
+   glMinmax
+      (marshalMinmaxTarget Minmax)
+      (marshalPixelInternalFormat' int)
+      (marshalSink sink)
+
+EXTENSION_ENTRY("GL_ARB_imaging",glMinmax,GLenum -> GLenum -> GLboolean -> IO ())
+
+--------------------------------------------------------------------------------
+
+getMinmax :: Reset -> PixelData a -> GL ()
+getMinmax reset pd = liftIO . 
+   withPixelData pd $
+      glGetMinmax (marshalMinmaxTarget Minmax) (marshalReset reset)
+
+EXTENSION_ENTRY("GL_ARB_imaging",glGetMinmax,GLenum -> GLboolean -> GLenum -> GLenum -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+resetMinmax :: GL ()
+resetMinmax = glResetMinmax (marshalMinmaxTarget Minmax)
+
+EXTENSION_ENTRY("GL_ARB_imaging",glResetMinmax,GLenum -> GL ())
+
+--------------------------------------------------------------------------------
+
+data GetMinmaxParameterPName =
+     MinmaxFormat
+   | MinmaxSink
+
+marshalGetMinmaxParameterPName :: GetMinmaxParameterPName -> GLenum
+marshalGetMinmaxParameterPName x = case x of
+   MinmaxFormat -> 0x802f
+   MinmaxSink -> 0x8030
+
+--------------------------------------------------------------------------------
+
+getMinmaxParameteri :: (GLint -> a) -> GetMinmaxParameterPName -> IO a
+getMinmaxParameteri f p =
+   alloca $ \buf -> do
+      glGetMinmaxParameteriv
+         (marshalMinmaxTarget Minmax)
+         (marshalGetMinmaxParameterPName p)
+         buf
+      peek1 f buf
+
+EXTENSION_ENTRY("GL_ARB_imaging",glGetMinmaxParameteriv,GLenum -> GLenum -> Ptr GLint -> IO ())
diff --git a/Graphics/Rendering/OGL/GL/PixelRectangles/PixelMap.hs b/Graphics/Rendering/OGL/GL/PixelRectangles/PixelMap.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PixelRectangles/PixelMap.hs
@@ -0,0 +1,247 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PixelRectangles.PixelMap
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to a part of section 3.6.1 (Pixel Storage Modes) of
+-- the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PixelRectangles.PixelMap (
+   PixelMapTarget(..), PixelMapComponent, PixelMap(..), GLpixelmap,
+   maxPixelMapTable, pixelMap, pixelMapIToRGBA, pixelMapRGBAToRGBA,
+) where
+
+import Data.List ( zipWith4 )
+import Data.Word
+import Foreign.ForeignPtr ( ForeignPtr, mallocForeignPtrArray, withForeignPtr )
+import Foreign.Marshal.Array ( allocaArray, peekArray, pokeArray, withArrayLen )
+import Foreign.Ptr ( Ptr )
+import Foreign.Storable ( Storable(..) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLenum, GLushort, GLuint, GLsizei, GLfloat )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetMaxPixelMapTable,GetPixelMapIToISize,GetPixelMapSToSSize,
+            GetPixelMapIToRSize,GetPixelMapIToGSize,GetPixelMapIToBSize,
+            GetPixelMapIToASize,GetPixelMapRToRSize,GetPixelMapGToGSize,
+            GetPixelMapBToBSize,GetPixelMapAToASize),
+   getInteger1, getSizei1 )
+import Graphics.Rendering.OGL.GL.StateVar (
+   HasSetter(($=)), HasGetter(get), GettableStateVar, makeGettableStateVar,
+   StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.VertexSpec ( Color4(..) )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLTypes.h"
+
+--------------------------------------------------------------------------------
+
+data PixelMapTarget =
+     IToI
+   | SToS
+   | IToR
+   | IToG
+   | IToB
+   | IToA
+   | RToR
+   | GToG
+   | BToB
+   | AToA
+
+marshalPixelMapTarget :: PixelMapTarget -> GLenum
+marshalPixelMapTarget x = case x of
+   IToI -> 0xc70
+   SToS -> 0xc71
+   IToR -> 0xc72
+   IToG -> 0xc73
+   IToB -> 0xc74
+   IToA -> 0xc75
+   RToR -> 0xc76
+   GToG -> 0xc77
+   BToB -> 0xc78
+   AToA -> 0xc79
+
+pixelMapTargetToGetPName :: PixelMapTarget -> GetPName
+pixelMapTargetToGetPName x = case x of
+   IToI -> GetPixelMapIToISize
+   SToS -> GetPixelMapSToSSize
+   IToR -> GetPixelMapIToRSize
+   IToG -> GetPixelMapIToGSize
+   IToB -> GetPixelMapIToBSize
+   IToA -> GetPixelMapIToASize
+   RToR -> GetPixelMapRToRSize
+   GToG -> GetPixelMapGToGSize
+   BToB -> GetPixelMapBToBSize
+   AToA -> GetPixelMapAToASize
+
+--------------------------------------------------------------------------------
+
+maxPixelMapTable :: GettableStateVar GLsizei
+maxPixelMapTable = makeGettableStateVar $ getSizei1 id GetMaxPixelMapTable
+
+--------------------------------------------------------------------------------
+
+class Storable c => PixelMapComponent c where
+   getPixelMapv :: GLenum -> Ptr c -> GL ()
+   pixelMapv :: GLenum -> GLsizei -> Ptr c -> GL ()
+
+instance PixelMapComponent GLushort_ where
+   getPixelMapv = glGetPixelMapusv
+   pixelMapv = glPixelMapusv
+
+foreign import CALLCONV unsafe "glGetPixelMapusv" glGetPixelMapusv ::
+   GLenum -> Ptr GLushort -> GL ()
+
+foreign import CALLCONV unsafe "glPixelMapusv" glPixelMapusv ::
+   GLenum -> GLsizei -> Ptr GLushort -> GL ()
+
+instance PixelMapComponent GLuint_ where
+   getPixelMapv = glGetPixelMapuiv
+   pixelMapv = glPixelMapuiv
+
+foreign import CALLCONV unsafe "glGetPixelMapuiv" glGetPixelMapuiv ::
+   GLenum -> Ptr GLuint -> GL ()
+
+foreign import CALLCONV unsafe "glPixelMapuiv" glPixelMapuiv ::
+   GLenum -> GLsizei -> Ptr GLuint -> GL ()
+
+instance PixelMapComponent GLfloat_ where
+   getPixelMapv = glGetPixelMapfv
+   pixelMapv = glPixelMapfv
+
+foreign import CALLCONV unsafe "glGetPixelMapfv" glGetPixelMapfv ::
+   GLenum -> Ptr GLfloat -> GL ()
+
+foreign import CALLCONV unsafe "glPixelMapfv" glPixelMapfv ::
+   GLenum -> GLsizei -> Ptr GLfloat -> GL ()
+
+--------------------------------------------------------------------------------
+
+class PixelMap m where
+   withNewPixelMap ::
+      PixelMapComponent c => Int -> (Ptr c -> GL ()) -> GL (m c)
+   withPixelMap ::
+      PixelMapComponent c => m c -> (Int -> Ptr c -> GL a) -> GL a
+   newPixelMap :: PixelMapComponent c => [c] -> GL (m c)
+   getPixelMapComponents :: PixelMapComponent c => m c -> GL [c]
+
+   withNewPixelMap size act = liftIO . 
+      allocaArray size $ \p -> do
+         runGL $ act p
+         components <- peekArray size p
+         runGL $ newPixelMap components
+
+   withPixelMap m act = do
+      components <- getPixelMapComponents m
+      liftIO $ withArrayLen components (\a b -> runGL $ act a b)
+
+   newPixelMap elements = 
+      withNewPixelMap (length elements) $ (liftIO . flip pokeArray elements)
+
+   getPixelMapComponents m = 
+      withPixelMap m (\a b -> liftIO $ peekArray a b)
+
+--------------------------------------------------------------------------------
+
+data GLpixelmap a = GLpixelmap Int (ForeignPtr a)
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq (GLpixelmap a)
+instance Ord (GLpixelmap a)
+instance Show (GLpixelmap a)
+#else
+   deriving ( Eq, Ord, Show )
+#endif
+
+instance PixelMap GLpixelmap where
+   withNewPixelMap size f = liftIO $ do
+      fp <- mallocForeignPtrArray size
+      withForeignPtr fp (runGL . f)
+      return $ GLpixelmap size fp
+
+   withPixelMap (GLpixelmap size fp) f = liftIO $ withForeignPtr fp (runGL . f size)
+
+--------------------------------------------------------------------------------
+
+pixelMap :: (PixelMap m, PixelMapComponent c) => PixelMapTarget -> StateVar (m c)
+pixelMap pm =
+   makeStateVar
+      (do size <- pixelMapSize pm
+          runGL . withNewPixelMap size $ getPixelMapv (marshalPixelMapTarget pm))
+      (\theMap -> runGL . withPixelMap theMap $ pixelMapv (marshalPixelMapTarget pm) . fromIntegral)
+
+pixelMapSize :: PixelMapTarget -> IO Int
+pixelMapSize = getInteger1 fromIntegral . pixelMapTargetToGetPName
+
+--------------------------------------------------------------------------------
+
+-- | Convenience state variable
+
+pixelMapIToRGBA :: PixelMapComponent c => StateVar [Color4 c]
+pixelMapIToRGBA = pixelMapXToY (IToR, IToG, IToB, IToA)
+
+-- | Convenience state variable
+
+pixelMapRGBAToRGBA :: PixelMapComponent c => StateVar [Color4 c]
+pixelMapRGBAToRGBA = pixelMapXToY (RToR, GToG, BToB, AToA)
+
+pixelMapXToY :: PixelMapComponent c =>
+      (PixelMapTarget, PixelMapTarget, PixelMapTarget, PixelMapTarget)
+   -> StateVar [Color4 c]
+pixelMapXToY targets =
+   makeStateVar (getPixelMapXToY targets) (setPixelMapXToY targets)
+
+getPixelMapXToY :: PixelMapComponent c
+   => (PixelMapTarget, PixelMapTarget, PixelMapTarget, PixelMapTarget)
+   -> IO [Color4 c]
+getPixelMapXToY (toR, toG, toB, toA) = do
+   withPixelMapFor toR $ \sizeR bufR ->
+      withPixelMapFor toG $ \sizeG bufG ->
+         withPixelMapFor toB $ \sizeB bufB ->
+            withPixelMapFor toA $ \sizeA bufA -> do
+               let maxSize = sizeR `max` sizeG `max` sizeB `max` sizeA
+               r <- sample sizeR bufR maxSize
+               g <- sample sizeR bufG maxSize
+               b <- sample sizeR bufB maxSize
+               a <- sample sizeR bufA maxSize
+               return $ zipWith4 Color4 r g b a
+
+withPixelMapFor ::
+    PixelMapComponent c => PixelMapTarget -> (Int -> Ptr c -> IO a) -> IO a
+withPixelMapFor target f = do
+    theMap <- runGL $ get (pixelMap target)
+    withGLpixelmap theMap f
+
+withGLpixelmap :: PixelMapComponent c
+               => GLpixelmap c -> (Int -> Ptr c -> IO a) -> IO a
+withGLpixelmap a b = runGL $ withPixelMap a (\x y -> liftIO $ b x y)
+
+sample :: Storable a => Int -> Ptr a -> Int -> IO [a]
+sample len ptr newLen = f (fromIntegral (newLen - 1)) []
+   where scale :: Float
+         scale = fromIntegral len / fromIntegral newLen
+         f l acc | l < 0     = return acc
+                 | otherwise = do e <- peekElemOff ptr (truncate (l * scale))
+                                  f (l - 1) (e : acc)
+
+setPixelMapXToY :: PixelMapComponent c
+   => (PixelMapTarget, PixelMapTarget, PixelMapTarget, PixelMapTarget)
+   -> [Color4 c] -> IO ()
+setPixelMapXToY (toR, toG, toB, toA) colors = do
+   (pixelMap toR $$=) =<< newGLpixelmap [ r | Color4 r _ _ _ <- colors ]
+   (pixelMap toG $$=) =<< newGLpixelmap [ g | Color4 _ g _ _ <- colors ]
+   (pixelMap toB $$=) =<< newGLpixelmap [ b | Color4 _ _ b _ <- colors ]
+   (pixelMap toA $$=) =<< newGLpixelmap [ a | Color4 _ _ _ a <- colors ]
+
+   where ($$=) x y = runGL $ x $= y
+   
+newGLpixelmap :: PixelMapComponent c => [c] -> IO (GLpixelmap c)
+newGLpixelmap = runGL . newPixelMap
diff --git a/Graphics/Rendering/OGL/GL/PixelRectangles/PixelStorage.hs b/Graphics/Rendering/OGL/GL/PixelRectangles/PixelStorage.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PixelRectangles/PixelStorage.hs
@@ -0,0 +1,129 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PixelRectangles.PixelStorage
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.6.1 (Pixel Storage Modes) of the
+-- OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PixelRectangles.PixelStorage (
+   PixelStoreDirection(..), swapBytes, lsbFirst, rowLength, skipRows,
+   skipPixels, rowAlignment, imageHeight, skipImages
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum, GLint )
+import Graphics.Rendering.OGL.GL.GLboolean (
+   marshalGLboolean, unmarshalGLboolean )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetUnpackSwapBytes,GetUnpackLSBFirst,GetUnpackRowLength,
+            GetUnpackSkipRows,GetUnpackSkipPixels,GetUnpackAlignment,
+            GetUnpackImageHeight,GetUnpackSkipImages,GetPackSwapBytes,
+            GetPackLSBFirst,GetPackRowLength,GetPackSkipRows,GetPackSkipPixels,
+            GetPackAlignment,GetPackImageHeight,GetPackSkipImages),
+   getBoolean1, getInteger1 )
+import Graphics.Rendering.OGL.GL.StateVar ( StateVar, makeStateVar )
+
+--------------------------------------------------------------------------------
+
+data PixelStoreDirection =
+     Pack
+   | Unpack
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+data PixelStore =
+     UnpackSwapBytes
+   | UnpackLSBFirst
+   | UnpackRowLength
+   | UnpackSkipRows
+   | UnpackSkipPixels
+   | UnpackAlignment
+   | PackSwapBytes
+   | PackLSBFirst
+   | PackRowLength
+   | PackSkipRows
+   | PackSkipPixels
+   | PackAlignment
+   | PackSkipImages
+   | PackImageHeight
+   | UnpackSkipImages
+   | UnpackImageHeight
+
+marshalPixelStore :: PixelStore -> GLenum
+marshalPixelStore x = case x of
+   UnpackSwapBytes -> 0xcf0
+   UnpackLSBFirst -> 0xcf1
+   UnpackRowLength -> 0xcf2
+   UnpackSkipRows -> 0xcf3
+   UnpackSkipPixels -> 0xcf4
+   UnpackAlignment -> 0xcf5
+   PackSwapBytes -> 0xd00
+   PackLSBFirst -> 0xd01
+   PackRowLength -> 0xd02
+   PackSkipRows -> 0xd03
+   PackSkipPixels -> 0xd04
+   PackAlignment -> 0xd05
+   PackSkipImages -> 0x806b
+   PackImageHeight -> 0x806c
+   UnpackSkipImages -> 0x806d
+   UnpackImageHeight -> 0x806e
+
+--------------------------------------------------------------------------------
+
+swapBytes :: PixelStoreDirection -> StateVar Bool
+swapBytes Pack   = pixelStoreb GetPackSwapBytes PackSwapBytes
+swapBytes Unpack = pixelStoreb GetUnpackSwapBytes UnpackSwapBytes
+
+lsbFirst :: PixelStoreDirection -> StateVar Bool
+lsbFirst Pack   = pixelStoreb GetPackLSBFirst PackLSBFirst
+lsbFirst Unpack = pixelStoreb GetUnpackLSBFirst UnpackLSBFirst
+
+rowLength :: PixelStoreDirection -> StateVar GLint
+rowLength Pack   = pixelStorei GetPackRowLength PackRowLength
+rowLength Unpack = pixelStorei GetUnpackRowLength UnpackRowLength
+
+skipRows :: PixelStoreDirection -> StateVar GLint
+skipRows Pack   = pixelStorei GetPackSkipRows PackSkipRows
+skipRows Unpack = pixelStorei GetUnpackSkipRows UnpackSkipRows
+
+skipPixels :: PixelStoreDirection -> StateVar GLint
+skipPixels Pack   = pixelStorei GetPackSkipPixels PackSkipPixels
+skipPixels Unpack = pixelStorei GetUnpackSkipPixels UnpackSkipPixels
+
+rowAlignment :: PixelStoreDirection -> StateVar GLint
+rowAlignment Pack   = pixelStorei GetPackAlignment PackAlignment
+rowAlignment Unpack = pixelStorei GetUnpackAlignment UnpackAlignment
+
+imageHeight :: PixelStoreDirection -> StateVar GLint
+imageHeight Pack   = pixelStorei GetPackImageHeight PackImageHeight
+imageHeight Unpack = pixelStorei GetUnpackImageHeight UnpackImageHeight
+
+skipImages :: PixelStoreDirection -> StateVar GLint
+skipImages Pack   = pixelStorei GetPackSkipImages PackSkipImages
+skipImages Unpack = pixelStorei GetUnpackSkipImages UnpackSkipImages
+
+--------------------------------------------------------------------------------
+
+pixelStoreb :: GetPName -> PixelStore -> StateVar Bool
+pixelStoreb pn ps =
+   makeStateVar
+      (getBoolean1 unmarshalGLboolean pn)
+      (glPixelStorei (marshalPixelStore ps) . marshalGLboolean)
+
+pixelStorei :: GetPName -> PixelStore -> StateVar GLint
+pixelStorei pn ps =
+   makeStateVar
+      (getInteger1 id pn)
+      (glPixelStorei (marshalPixelStore ps))
+
+foreign import CALLCONV unsafe "glPixelStorei" glPixelStorei ::
+   GLenum -> GLint -> IO ()
diff --git a/Graphics/Rendering/OGL/GL/PixelRectangles/PixelTransfer.hs b/Graphics/Rendering/OGL/GL/PixelRectangles/PixelTransfer.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PixelRectangles/PixelTransfer.hs
@@ -0,0 +1,254 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PixelRectangles.PixelTransfer
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to a part of section 3.6.1 (Pixel Storage Modes) of
+-- the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PixelRectangles.PixelTransfer (
+   PixelTransferStage(..),
+   mapColor, mapStencil, indexShift, indexOffset, depthScale, depthBias,
+   rgbaScale, rgbaBias
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   marshalCapability, unmarshalCapability )
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLenum, GLint, GLfloat, Capability )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetMapColor,GetMapStencil,GetIndexShift,GetIndexOffset,
+            GetRedScale,GetGreenScale,GetBlueScale,GetAlphaScale,GetDepthScale,
+            GetRedBias,GetGreenBias,GetBlueBias,GetAlphaBias,GetDepthBias,
+            GetPostConvolutionRedScale,GetPostConvolutionGreenScale,
+            GetPostConvolutionBlueScale,GetPostConvolutionAlphaScale,
+            GetPostConvolutionRedBias,GetPostConvolutionGreenBias,
+            GetPostConvolutionBlueBias,GetPostConvolutionAlphaBias,
+            GetPostColorMatrixRedScale,GetPostColorMatrixGreenScale,
+            GetPostColorMatrixBlueScale,GetPostColorMatrixAlphaScale,
+            GetPostColorMatrixRedBias,GetPostColorMatrixGreenBias,
+            GetPostColorMatrixBlueBias,GetPostColorMatrixAlphaBias),
+   getBoolean1, getInteger1, getFloat1 )
+import Graphics.Rendering.OGL.GL.StateVar ( StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.VertexSpec ( Color4(..) )
+
+--------------------------------------------------------------------------------
+
+data PixelTransfer =
+     MapColor
+   | MapStencil
+   | IndexShift
+   | IndexOffset
+   | RedScale
+   | RedBias
+   | GreenScale
+   | GreenBias
+   | BlueScale
+   | BlueBias
+   | AlphaScale
+   | AlphaBias
+   | DepthScale
+   | DepthBias
+   | PostConvolutionRedScale
+   | PostConvolutionGreenScale
+   | PostConvolutionBlueScale
+   | PostConvolutionAlphaScale
+   | PostConvolutionRedBias
+   | PostConvolutionGreenBias
+   | PostConvolutionBlueBias
+   | PostConvolutionAlphaBias
+   | PostColorMatrixRedScale
+   | PostColorMatrixGreenScale
+   | PostColorMatrixBlueScale
+   | PostColorMatrixAlphaScale
+   | PostColorMatrixRedBias
+   | PostColorMatrixGreenBias
+   | PostColorMatrixBlueBias
+   | PostColorMatrixAlphaBias
+
+marshalPixelTransfer :: PixelTransfer -> GLenum
+marshalPixelTransfer x = case x of
+   MapColor -> 0xd10
+   MapStencil -> 0xd11
+   IndexShift -> 0xd12
+   IndexOffset -> 0xd13
+   RedScale -> 0xd14
+   RedBias -> 0xd15
+   GreenScale -> 0xd18
+   GreenBias -> 0xd19
+   BlueScale -> 0xd1a
+   BlueBias -> 0xd1b
+   AlphaScale -> 0xd1c
+   AlphaBias -> 0xd1d
+   DepthScale -> 0xd1e
+   DepthBias -> 0xd1f
+   PostConvolutionRedScale -> 0x801c
+   PostConvolutionGreenScale -> 0x801d
+   PostConvolutionBlueScale -> 0x801e
+   PostConvolutionAlphaScale -> 0x801f
+   PostConvolutionRedBias -> 0x8020
+   PostConvolutionGreenBias -> 0x8021
+   PostConvolutionBlueBias -> 0x8022
+   PostConvolutionAlphaBias -> 0x8023
+   PostColorMatrixRedScale -> 0x80b4
+   PostColorMatrixGreenScale -> 0x80b5
+   PostColorMatrixBlueScale -> 0x80b6
+   PostColorMatrixAlphaScale -> 0x80b7
+   PostColorMatrixRedBias -> 0x80b8
+   PostColorMatrixGreenBias -> 0x80b9
+   PostColorMatrixBlueBias -> 0x80ba
+   PostColorMatrixAlphaBias -> 0x80bb
+
+--------------------------------------------------------------------------------
+
+data PixelTransferStage =
+     PreConvolution
+   | PostConvolution
+   | PostColorMatrix
+   deriving ( Eq, Ord, Show )
+
+stageToGetScales ::
+      PixelTransferStage
+   -> (GetPName, GetPName, GetPName, GetPName)
+stageToGetScales s = case s of
+   PreConvolution  -> (GetRedScale,
+                       GetGreenScale,
+                       GetBlueScale,
+                       GetAlphaScale)
+   PostConvolution -> (GetPostConvolutionRedScale,
+                       GetPostConvolutionGreenScale,
+                       GetPostConvolutionBlueScale,
+                       GetPostConvolutionAlphaScale)
+   PostColorMatrix -> (GetPostColorMatrixRedScale,
+                       GetPostColorMatrixGreenScale,
+                       GetPostColorMatrixBlueScale,
+                       GetPostColorMatrixAlphaScale)
+
+stageToSetScales ::
+      PixelTransferStage
+   -> (PixelTransfer, PixelTransfer, PixelTransfer, PixelTransfer)
+stageToSetScales s = case s of
+   PreConvolution  -> (RedScale,
+                       GreenScale,
+                       BlueScale,
+                       AlphaScale)
+   PostConvolution -> (PostConvolutionRedScale,
+                       PostConvolutionGreenScale,
+                       PostConvolutionBlueScale,
+                       PostConvolutionAlphaScale)
+   PostColorMatrix -> (PostColorMatrixRedScale,
+                       PostColorMatrixGreenScale,
+                       PostColorMatrixBlueScale,
+                       PostColorMatrixAlphaScale)
+
+stageToGetBiases ::
+      PixelTransferStage
+   -> (GetPName, GetPName, GetPName, GetPName)
+stageToGetBiases s = case s of
+   PreConvolution  -> (GetRedBias,
+                       GetGreenBias,
+                       GetBlueBias,
+                       GetAlphaBias)
+   PostConvolution -> (GetPostConvolutionRedBias,
+                       GetPostConvolutionGreenBias,
+                       GetPostConvolutionBlueBias,
+                       GetPostConvolutionAlphaBias)
+   PostColorMatrix -> (GetPostColorMatrixRedBias,
+                       GetPostColorMatrixGreenBias,
+                       GetPostColorMatrixBlueBias,
+                       GetPostColorMatrixAlphaBias)
+
+stageToSetBiases ::
+      PixelTransferStage
+   -> (PixelTransfer, PixelTransfer, PixelTransfer, PixelTransfer)
+stageToSetBiases s = case s of
+   PreConvolution  -> (RedBias,
+                       GreenBias,
+                       BlueBias,
+                       AlphaBias)
+   PostConvolution -> (PostConvolutionRedBias,
+                       PostConvolutionGreenBias,
+                       PostConvolutionBlueBias,
+                       PostConvolutionAlphaBias)
+   PostColorMatrix -> (PostColorMatrixRedBias,
+                       PostColorMatrixGreenBias,
+                       PostColorMatrixBlueBias,
+                       PostColorMatrixAlphaBias)
+
+--------------------------------------------------------------------------------
+
+mapColor :: StateVar Capability
+mapColor = pixelTransferb GetMapColor MapColor
+
+mapStencil :: StateVar Capability
+mapStencil = pixelTransferb GetMapStencil MapStencil
+
+indexShift :: StateVar GLint
+indexShift = pixelTransferi GetIndexShift IndexShift
+
+indexOffset :: StateVar GLint
+indexOffset = pixelTransferi GetIndexOffset IndexOffset
+
+depthScale :: StateVar GLfloat
+depthScale = pixelTransferf GetDepthScale DepthScale
+
+depthBias :: StateVar GLfloat
+depthBias = pixelTransferf GetDepthBias DepthBias
+
+rgbaScale :: PixelTransferStage -> StateVar (Color4 GLfloat)
+rgbaScale s = pixelTransfer4f (stageToGetScales s) (stageToSetScales s)
+
+rgbaBias :: PixelTransferStage -> StateVar (Color4 GLfloat)
+rgbaBias s = pixelTransfer4f (stageToGetBiases s) (stageToSetBiases s)
+
+--------------------------------------------------------------------------------
+
+pixelTransferb :: GetPName -> PixelTransfer -> StateVar Capability
+pixelTransferb pn pt =
+   makeStateVar
+      (getBoolean1 unmarshalCapability pn)
+      (glPixelTransferi (marshalPixelTransfer pt) .
+       fromIntegral . marshalCapability)
+
+pixelTransferi :: GetPName -> PixelTransfer -> StateVar GLint
+pixelTransferi pn pt =
+   makeStateVar
+      (getInteger1 id pn)
+      (glPixelTransferi (marshalPixelTransfer pt))
+
+foreign import CALLCONV unsafe "glPixelTransferi" glPixelTransferi ::
+   GLenum -> GLint -> IO ()
+
+pixelTransferf :: GetPName -> PixelTransfer -> StateVar GLfloat
+pixelTransferf pn pt =
+   makeStateVar
+      (getFloat1 id pn)
+      (glPixelTransferf (marshalPixelTransfer pt))
+
+pixelTransfer4f ::
+      (GetPName,      GetPName,      GetPName,      GetPName)
+   -> (PixelTransfer, PixelTransfer, PixelTransfer, PixelTransfer)
+   -> StateVar (Color4 GLfloat)
+pixelTransfer4f (pr, pg, pb, pa) (tr, tg, tb, ta) = makeStateVar get4f set4f
+   where get4f = do
+            r <- getFloat1 id pr
+            g <- getFloat1 id pg
+            b <- getFloat1 id pb
+            a <- getFloat1 id pa
+            return $ Color4 r g b a
+         set4f (Color4 r g b a) = do
+            glPixelTransferf (marshalPixelTransfer tr) r
+            glPixelTransferf (marshalPixelTransfer tg) g
+            glPixelTransferf (marshalPixelTransfer tb) b
+            glPixelTransferf (marshalPixelTransfer ta) a
+
+foreign import CALLCONV unsafe "glPixelTransferf" glPixelTransferf ::
+   GLenum -> GLfloat -> IO ()
diff --git a/Graphics/Rendering/OGL/GL/PixelRectangles/Rasterization.hs b/Graphics/Rendering/OGL/GL/PixelRectangles/Rasterization.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PixelRectangles/Rasterization.hs
@@ -0,0 +1,48 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PixelRectangles.Rasterization
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to a part of section 3.6.4 (Rasterization of Pixel
+-- Rectangles) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PixelRectangles.Rasterization (
+   PixelData(..), PixelFormat(..), drawPixels, pixelZoom
+) where
+
+import Control.Monad ( liftM2 )
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum, GLsizei, GLfloat )
+import Graphics.Rendering.OGL.GL.CoordTrans ( Size(..) )
+import Graphics.Rendering.OGL.GL.PixelData ( PixelData(..), withPixelData )
+import Graphics.Rendering.OGL.GL.PixelFormat ( PixelFormat(..) )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetZoomX,GetZoomY), getFloat1 )
+import Graphics.Rendering.OGL.GL.StateVar ( StateVar, makeStateVar )
+
+--------------------------------------------------------------------------------
+
+drawPixels :: Size -> PixelData a -> GL ()
+drawPixels (Size w h) pd = liftIO . withPixelData pd $ glDrawPixels w h
+
+foreign import CALLCONV unsafe "glDrawPixels" glDrawPixels ::
+   GLsizei -> GLsizei -> GLenum -> GLenum -> Ptr a -> IO ()
+
+--------------------------------------------------------------------------------
+
+pixelZoom :: StateVar (GLfloat, GLfloat)
+pixelZoom =
+   makeStateVar
+      (liftM2 (,) (getFloat1 id GetZoomX) (getFloat1 id GetZoomY))
+      (uncurry glPixelZoom)
+
+foreign import CALLCONV unsafe "glPixelZoom" glPixelZoom ::
+   GLfloat -> GLfloat -> IO ()
diff --git a/Graphics/Rendering/OGL/GL/PixelRectangles/Reset.hs b/Graphics/Rendering/OGL/GL/PixelRectangles/Reset.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PixelRectangles/Reset.hs
@@ -0,0 +1,31 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PixelRectangles.Reset
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for (un-)marshaling Reset.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PixelRectangles.Reset (
+   Reset(..), marshalReset
+) where
+
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLboolean )
+import Graphics.Rendering.OGL.GL.GLboolean ( marshalGLboolean )
+
+--------------------------------------------------------------------------------
+
+data Reset =
+     NoReset
+   | Reset
+   deriving ( Eq, Ord, Show )
+
+marshalReset :: Reset -> GLboolean
+marshalReset x = marshalGLboolean (x == Reset)
diff --git a/Graphics/Rendering/OGL/GL/PixelRectangles/Sink.hs b/Graphics/Rendering/OGL/GL/PixelRectangles/Sink.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PixelRectangles/Sink.hs
@@ -0,0 +1,35 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PixelRectangles.Sink
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for (un-)marshaling Sink.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PixelRectangles.Sink (
+   Sink(..), marshalSink, unmarshalSink
+) where
+
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLboolean, GLint )
+import Graphics.Rendering.OGL.GL.GLboolean (
+   marshalGLboolean, unmarshalGLboolean )
+
+--------------------------------------------------------------------------------
+
+data Sink =
+     PassThrough
+   | Sink
+   deriving ( Eq, Ord, Show )
+
+marshalSink :: Sink -> GLboolean
+marshalSink x = marshalGLboolean (x == Sink)
+
+unmarshalSink :: GLint -> Sink
+unmarshalSink s = if unmarshalGLboolean s then Sink else PassThrough
diff --git a/Graphics/Rendering/OGL/GL/PointParameter.hs b/Graphics/Rendering/OGL/GL/PointParameter.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PointParameter.hs
@@ -0,0 +1,55 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PointParameter
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for setting point parameters.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PointParameter (
+   PointParameter(..), pointParameterf, pointParameterfv
+) where
+
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum, GLfloat )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+
+--------------------------------------------------------------------------------
+
+data PointParameter =
+     PointSizeMin
+   | PointSizeMax
+   | PointFadeThresholdSize
+   | PointDistanceAttenuation
+
+marshalPointParameter :: PointParameter -> GLenum
+marshalPointParameter x = case x of
+   PointSizeMin -> 0x8126
+   PointSizeMax -> 0x8127
+   PointFadeThresholdSize -> 0x8128
+   PointDistanceAttenuation -> 0x8129
+
+--------------------------------------------------------------------------------
+
+pointParameterf :: PointParameter -> GLfloat -> IO ()
+pointParameterf = glPointParameterfARB . marshalPointParameter
+
+EXTENSION_ENTRY("GL_ARB_point_parameters or OpenGL 1.4",glPointParameterfARB,GLenum -> GLfloat -> IO ())
+
+pointParameterfv :: PointParameter -> Ptr GLfloat -> IO ()
+pointParameterfv = glPointParameterfvARB . marshalPointParameter
+
+EXTENSION_ENTRY("GL_ARB_point_parameters or OpenGL 1.4",glPointParameterfvARB,GLenum -> Ptr GLfloat -> IO ())
diff --git a/Graphics/Rendering/OGL/GL/Points.hs b/Graphics/Rendering/OGL/GL/Points.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Points.hs
@@ -0,0 +1,228 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Points
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.3 (Points) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Points (
+   -- * Point Rasterization
+   pointSize, vertexProgramPointSize,
+
+   -- * Controlling the Derived Size
+   pointSizeRange, pointDistanceAttenuation,
+
+   -- * Fading Points
+   pointFadeThresholdSize,
+
+   -- * Point Antialiasing
+   pointSmooth,
+
+   -- * Point Sprites
+   pointSprite,
+
+   -- * Implementation-Dependent Limits
+   aliasedPointSizeRange, smoothPointSizeRange, smoothPointSizeGranularity
+) where
+
+import Control.Monad ( liftM2 )
+import Foreign.Marshal.Array ( withArray )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapVertexProgramPointSize,CapPointSmooth,CapPointSprite),
+   makeCapability )
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLfloat, Capability )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetPointSize,GetAliasedPointSizeRange,GetSmoothPointSizeRange,
+            GetSmoothPointSizeGranularity,GetPointSizeMin,GetPointSizeMax,
+            GetPointDistanceAttenuation,GetPointFadeThresholdSize),
+   getFloat1, getFloat2, getFloat3 )
+import Graphics.Rendering.OGL.GL.PointParameter (
+   PointParameter(..), pointParameterf, pointParameterfv )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )
+
+--------------------------------------------------------------------------------
+
+-- | 'pointSize' contains the rasterized diameter of both aliased and
+-- antialiased points. The initial value is 1. Using a point size other than 1
+-- has different effects, depending on whether point antialiasing is enabled
+-- (see 'pointSmooth') or point sprites are enabled (see 'pointSprite'). Both
+-- are initially disabled.
+--
+-- The specified point size is multiplied with a distance attenuation factor
+-- and clamped to the specified 'pointSizeRange', and further clamped to the
+-- implementation-dependent point size range to produce the derived point size
+-- using
+--
+-- @   /derivedSize/ = /clamp/ (/size/ * /sqrt/ (1 \/ (/a/ + /b/ * /d/ + /c/ * /d/^2)))@
+--
+-- where /d/ is the eye-coordinate distance from the eye to the vertex, and /a/,
+-- /b/, and /c/ are the distance attenuation coefficients (see
+-- 'pointDistanceAttenuation').
+--
+-- If multisampling is disabled, the computed point size is used as the point\'s
+-- width.
+--
+-- If multisampling is enabled, the point may be faded by modifying the point
+-- alpha value (see 'Graphics.Rendering.OGL.GL.PerFragment.sampleCoverage')
+-- instead of allowing the point width to go below a given
+-- 'pointFadeThresholdSize'. In this case, the width is further modified in
+-- the following manner:
+--
+-- @   /width/ = if /derivedSize/ >= /threshold/ then /derivedSize/ else /threshold/@
+--
+-- The point alpha value is modified by computing:
+--
+-- @   /alpha/ = if /derivedSize/ >= /threshold/ then 1 else (/derivedSize/ \/ /threshold/)^2@
+--
+-- If point antialiasing is disabled, the actual size is determined by rounding
+-- the supplied size to the nearest integer. (If the rounding results in the
+-- value 0, it is as if the point size were 1.) If the rounded size is odd,
+-- then the center point (/x/, /y/) of the pixel fragment that represents
+-- the point is computed as
+--
+-- @   (/x/, /y/) = (/floor/ /xw/ + 0.5, /floor/ /yw/ + 0.5)@
+--
+-- where /xw/ and /yw/ indicate window coordinates. All pixels that lie within
+-- the square grid of the rounded size centered at (/x/, /y/) make up the
+-- fragment. If the size is even, the center point is
+--
+-- @   (/x/, /y/) = (/floor/ (/xw/ + 0.5), /floor/ (/yw/ + 0.5))@
+--
+-- and the rasterized fragment\'s centers are the half-integer window
+-- coordinates within the square of the rounded size centered at (/x/, /y/). All
+-- pixel fragments produced in rasterizing a nonantialiased point are assigned
+-- the same associated data, that of the vertex corresponding to the point.
+--
+-- If antialiasing is enabled, then point rasterization produces a fragment for
+-- each pixel square that intersects the region lying within the circle having
+-- diameter equal to the current point size and centered at the point\'s
+-- (/xw/, /yw/). The coverage value for each fragment is the window coordinate
+-- area of the intersection of the circular region with the corresponding pixel
+-- square. This value is saved and used in the final rasterization step. The
+-- data associated with each fragment is the data associated with the point
+-- being rasterized.
+--
+-- Not all sizes are supported when point antialiasing is enabled. If an
+-- unsupported size is requested, the nearest supported size is used.  Only size
+-- 1 is guaranteed to be supported; others depend on the implementation. To
+-- query the range of supported sizes for antialiased points and the size
+-- difference between supported sizes within the range, query
+-- 'smoothPointSizeRange' and 'smoothPointSizeGranularity', respectively. For
+-- aliased points, query the supported range with 'aliasedPointSizeRange'.
+--
+-- The point size specified when 'pointSize' is set is always returned when it
+-- is queried. Clamping and rounding for aliased and antialiased points have no
+-- effect on the specified value.
+--
+-- A non-antialiased point size may be clamped to an implementation-dependent
+-- maximum. Although this maximum cannot be queried, it must be no less than the
+-- maximum value for antialiased points, rounded to the nearest integer value.
+--
+-- An 'Graphics.Rendering.OGL.GLU.Errors.InvalidValue' is generated if
+-- 'pointSize' is set to a value less than or equal to zero.
+--
+-- An 'Graphics.Rendering.OGL.GLU.Errors.InvalidOperation' is generated if
+-- 'pointSize' is set during
+-- 'Graphics.Rendering.OGL.GL.BeginEnd.renderPrimitive'.
+
+pointSize :: StateVar GLfloat
+pointSize = makeStateVar (getFloat1 id GetPointSize) glPointSize
+
+foreign import CALLCONV unsafe "glPointSize" glPointSize :: GLfloat -> IO ()
+
+--------------------------------------------------------------------------------
+
+vertexProgramPointSize :: StateVar Capability
+vertexProgramPointSize = makeCapability CapVertexProgramPointSize
+
+--------------------------------------------------------------------------------
+
+-- | The range to which the derived point size is clamped, see 'pointSize'. Note
+-- that the size is further clamped to the implementation-dependent limits, see
+-- 'aliasedPointSizeRange' and 'smoothPointSizeRange'. The initial range is
+-- (0, 1).
+--
+-- An 'Graphics.Rendering.OGL.GLU.Errors.InvalidValue' is generated if the
+-- lower or upper bound of the range is set to a value less than zero. If the
+-- lower bound is greater than the upper bound, the point size after clamping is
+-- undefined, but no error is generated.
+
+pointSizeRange :: StateVar (GLfloat, GLfloat)
+pointSizeRange =
+   makeStateVar
+   (liftM2 (,) (getFloat1 id GetPointSizeMin) (getFloat1 id GetPointSizeMax))
+   (\(sizeMin, sizeMax) -> do pointParameterf PointSizeMin sizeMin
+                              pointParameterf PointSizeMax sizeMax)
+
+--------------------------------------------------------------------------------
+
+-- | The  constant, linear, and quadratic distance attenuation coefficients, see
+-- 'pointSize'. The initial coefficients are (1, 0, 0).
+
+pointDistanceAttenuation :: StateVar (GLfloat, GLfloat, GLfloat)
+pointDistanceAttenuation =
+   makeStateVar
+      (getFloat3 (,,) GetPointDistanceAttenuation)
+      (\(a, b, c) -> withArray [a, b, c] $
+                        pointParameterfv PointDistanceAttenuation)
+
+--------------------------------------------------------------------------------
+
+-- | The threshold for alpha attenuation of points when multisampling is used,
+-- see 'pointSize'. The initial threshold is 1.
+--
+-- An 'Graphics.Rendering.OGL.GLU.Errors.InvalidValue' is generated if the
+-- threshold is set to a value less than zero.
+
+pointFadeThresholdSize :: StateVar GLfloat
+pointFadeThresholdSize =
+   makeStateVar
+      (getFloat1 id GetPointFadeThresholdSize)
+      (pointParameterf PointFadeThresholdSize)
+
+--------------------------------------------------------------------------------
+
+-- | Controls whether point antialiasing is enabled. The initial state is
+-- 'Graphics.Rendering.OGL.GL.BasicTypes.Disabled'.
+
+pointSmooth :: StateVar Capability
+pointSmooth = makeCapability CapPointSmooth
+
+--------------------------------------------------------------------------------
+
+-- | Controls whether point sprites are enabled. The initial state is
+-- 'Graphics.Rendering.OGL.GL.BasicTypes.Disabled'. When point sprites are
+-- enabled, the state of point antialiasing (i.e. 'pointSmooth') is ignored.
+
+pointSprite :: StateVar Capability
+pointSprite = makeCapability CapPointSprite
+
+--------------------------------------------------------------------------------
+
+-- | The smallest and largest supported size of aliased points.
+
+aliasedPointSizeRange :: GettableStateVar (GLfloat, GLfloat)
+aliasedPointSizeRange =
+   makeGettableStateVar $ getFloat2 (,) GetAliasedPointSizeRange
+
+-- | The smallest and largest supported size of antialiased points.
+
+smoothPointSizeRange :: GettableStateVar (GLfloat, GLfloat)
+smoothPointSizeRange =
+   makeGettableStateVar $ getFloat2 (,) GetSmoothPointSizeRange
+
+-- | The antialiased point size granularity, i.e. the size difference between
+-- supported sizes.
+
+smoothPointSizeGranularity :: GettableStateVar GLfloat
+smoothPointSizeGranularity =
+   makeGettableStateVar $ getFloat1 id GetSmoothPointSizeGranularity
diff --git a/Graphics/Rendering/OGL/GL/PolygonMode.hs b/Graphics/Rendering/OGL/GL/PolygonMode.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PolygonMode.hs
@@ -0,0 +1,41 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PolygonMode
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for (un-)marshaling PolygonMode.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PolygonMode (
+   PolygonMode(..), marshalPolygonMode, unmarshalPolygonMode
+) where
+
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum )
+
+--------------------------------------------------------------------------------
+
+data PolygonMode =
+     Point
+   | Line
+   | Fill
+   deriving ( Eq, Ord, Show )
+
+marshalPolygonMode :: PolygonMode -> GLenum
+marshalPolygonMode x = case x of
+   Point -> 0x1b00
+   Line -> 0x1b01
+   Fill -> 0x1b02
+
+unmarshalPolygonMode :: GLenum -> PolygonMode
+unmarshalPolygonMode x
+   | x == 0x1b00 = Point
+   | x == 0x1b01 = Line
+   | x == 0x1b02 = Fill
+   | otherwise = error ("unmarshalPolygonMode: illegal value " ++ show x)
diff --git a/Graphics/Rendering/OGL/GL/Polygons.hs b/Graphics/Rendering/OGL/GL/Polygons.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Polygons.hs
@@ -0,0 +1,164 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Polygons
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.5 (Polygons) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Polygons (
+   polygonSmooth, cullFace,
+   PolygonStipple(..), GLpolygonstipple, polygonStipple,
+   PolygonMode(..), polygonMode, polygonOffset,
+   polygonOffsetPoint, polygonOffsetLine, polygonOffsetFill
+) where
+
+import Control.Monad ( liftM2 )
+import Foreign.ForeignPtr ( ForeignPtr, mallocForeignPtrArray, withForeignPtr )
+import Foreign.Marshal.Array ( allocaArray, withArray, peekArray, pokeArray )
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapPolygonSmooth,CapCullFace,CapPolygonStipple,
+             CapPolygonOffsetPoint,CapPolygonOffsetLine,CapPolygonOffsetFill),
+   makeCapability, makeStateVarMaybe )
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLenum, GLubyte, GLfloat, Capability )
+import Graphics.Rendering.OGL.GL.Face ( marshalFace, unmarshalFace )
+import Graphics.Rendering.OGL.GL.Colors ( Face(..) )
+import Graphics.Rendering.OGL.GL.PixelRectangles (
+   PixelStoreDirection(..), rowLength, skipRows, skipPixels )
+import Graphics.Rendering.OGL.GL.PolygonMode (
+   PolygonMode(..), marshalPolygonMode, unmarshalPolygonMode )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetCullFaceMode,GetPolygonMode,GetPolygonOffsetFactor,
+            GetPolygonOffsetUnits),
+   getInteger2, getEnum1, getFloat1 )
+import Graphics.Rendering.OGL.GL.SavingState (
+   ClientAttributeGroup(PixelStoreAttributes), preservingClientAttrib )
+import Graphics.Rendering.OGL.GL.StateVar (
+   HasSetter(($=)), StateVar, makeStateVar )
+
+--------------------------------------------------------------------------------
+
+polygonSmooth :: StateVar Capability
+polygonSmooth = makeCapability CapPolygonSmooth
+
+--------------------------------------------------------------------------------
+
+cullFace :: StateVar (Maybe Face)
+cullFace = makeStateVarMaybe (return CapCullFace)
+                             (getEnum1 unmarshalFace GetCullFaceMode)
+                             (glCullFace . marshalFace)
+
+foreign import CALLCONV unsafe "glCullFace" glCullFace :: GLenum -> IO ()
+
+--------------------------------------------------------------------------------
+
+numPolygonStippleBytes :: Int
+numPolygonStippleBytes = 128   -- 32x32 bits divided into GLubytes
+
+class PolygonStipple s where
+   withNewPolygonStipple :: (Ptr GLubyte -> GL ()) -> GL s
+   withPolygonStipple :: s -> (Ptr GLubyte -> GL a) -> GL a
+   newPolygonStipple :: [GLubyte] -> GL s
+   getPolygonStippleComponents :: s -> GL [GLubyte]
+
+   withNewPolygonStipple act = liftIO .
+      allocaArray numPolygonStippleBytes $ \p -> do
+         runGL $ act p
+         components <- peekArray numPolygonStippleBytes p
+         runGL $ newPolygonStipple components
+
+   withPolygonStipple s act = do
+      components <- getPolygonStippleComponents s
+      liftIO $ withArray components (runGL . act)
+
+   newPolygonStipple components =
+      withNewPolygonStipple $ liftIO . 
+         flip pokeArray (take numPolygonStippleBytes components)
+
+   getPolygonStippleComponents s =
+      withPolygonStipple s $ liftIO . peekArray numPolygonStippleBytes
+
+--------------------------------------------------------------------------------
+
+data GLpolygonstipple = GLpolygonstipple (ForeignPtr GLubyte)
+   deriving ( Eq, Ord, Show )
+
+instance PolygonStipple GLpolygonstipple where
+   withNewPolygonStipple f = liftIO $ do
+      fp <- mallocForeignPtrArray numPolygonStippleBytes
+      withForeignPtr fp (runGL . f)
+      return $ GLpolygonstipple fp
+
+   withPolygonStipple (GLpolygonstipple fp) f = liftIO $ withForeignPtr fp (runGL . f)
+
+--------------------------------------------------------------------------------
+
+polygonStipple :: PolygonStipple s => StateVar (Maybe s)
+polygonStipple = 
+   makeStateVarMaybe (return CapPolygonStipple)
+      (withoutGaps Pack . runGL $ withNewPolygonStipple glGetPolygonStipple)
+      (\s -> withoutGaps Unpack . runGL $ withPolygonStipple s glPolygonStipple)
+
+-- Note: No need to set rowAlignment, our memory allocator always returns a
+-- region which is at least 8-byte aligned (the maximum)
+withoutGaps :: PixelStoreDirection -> IO a -> IO a
+withoutGaps direction action = runGL .
+   preservingClientAttrib [ PixelStoreAttributes ] $ do
+      rowLength  direction $= 0
+      skipRows   direction $= 0
+      skipPixels direction $= 0
+      (liftIO action)
+
+foreign import CALLCONV unsafe "glGetPolygonStipple" glGetPolygonStipple ::
+   Ptr GLubyte -> GL ()
+
+foreign import CALLCONV unsafe "glPolygonStipple" glPolygonStipple ::
+   Ptr GLubyte -> GL ()
+
+--------------------------------------------------------------------------------
+
+polygonMode :: StateVar (PolygonMode, PolygonMode)
+polygonMode = makeStateVar getPolygonMode setPolygonMode
+
+getPolygonMode :: IO (PolygonMode, PolygonMode)
+getPolygonMode = getInteger2 (\front back -> (un front, un back)) GetPolygonMode
+   where un = unmarshalPolygonMode . fromIntegral
+
+setPolygonMode :: (PolygonMode, PolygonMode) -> IO ()
+setPolygonMode (front, back) = do
+   glPolygonMode (marshalFace Front) (marshalPolygonMode front)
+   glPolygonMode (marshalFace Back ) (marshalPolygonMode back )
+
+foreign import CALLCONV unsafe "glPolygonMode" glPolygonMode ::
+   GLenum -> GLenum -> IO ()
+
+--------------------------------------------------------------------------------
+
+polygonOffset :: StateVar (GLfloat, GLfloat)
+polygonOffset =
+   makeStateVar (liftM2 (,) (getFloat1 id GetPolygonOffsetFactor)
+                            (getFloat1 id GetPolygonOffsetUnits))
+                (uncurry glPolygonOffset)
+
+foreign import CALLCONV unsafe "glPolygonOffset" glPolygonOffset ::
+   GLfloat -> GLfloat -> IO ()
+
+--------------------------------------------------------------------------------
+
+polygonOffsetPoint :: StateVar Capability
+polygonOffsetPoint = makeCapability CapPolygonOffsetPoint
+
+polygonOffsetLine :: StateVar Capability
+polygonOffsetLine = makeCapability CapPolygonOffsetLine
+
+polygonOffsetFill :: StateVar Capability
+polygonOffsetFill = makeCapability CapPolygonOffsetFill
diff --git a/Graphics/Rendering/OGL/GL/PrimitiveMode.hs b/Graphics/Rendering/OGL/GL/PrimitiveMode.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/PrimitiveMode.hs
@@ -0,0 +1,96 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.PrimitiveMode
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for (un-)marshaling PrimitiveMode.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.PrimitiveMode (
+   PrimitiveMode(..), marshalPrimitiveMode, unmarshalPrimitiveMode
+) where
+
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum )
+
+--------------------------------------------------------------------------------
+
+-- | Specification of the way the vertices given during 'renderPrimitive' are
+-- interpreted. In the description of the constructors, /n/ is an integer count
+-- starting at one, and /N/ is the total number of vertices specified.
+
+data PrimitiveMode =
+     Points
+     -- ^ Treats each vertex as a single point. Vertex /n/ defines point /n/.
+     -- /N/ points are drawn.
+   | Lines
+     -- ^ Treats each pair of vertices as an independent line segment. Vertices
+     -- 2/n/-1 and 2/n/ define line /n/. /N/\/2 lines are drawn.
+   | LineLoop
+     -- ^ Draws a connected group of line segments from the first vertex to the
+     -- last, then back to the first. Vertices /n/ and /n/+1 define line /n/.
+     -- The last line, however, is defined by vertices /N/ and 1. /N/ lines
+     -- are drawn.
+   | LineStrip
+     -- ^ Draws a connected group of line  segments from the first vertex to the
+     -- last. Vertices /n/ and /n/+1 define line /n/. /N/-1 lines are drawn.
+   | Triangles
+     -- ^ Treats each triplet of vertices as an independent triangle. Vertices
+     -- /3n-2/, /3n-1/, and /3n/ define triangle /n/. /N\/3/ triangles are drawn.
+   | TriangleStrip
+     -- ^ Draws a connected group of triangles. One triangle is defined for each
+     -- vertex presented after the first two vertices. For odd /n/, vertices
+     -- /n/, /n/+1, and /n/+2 define triangle /n/. For even /n/, vertices /n/+1,
+     -- /n/, and /n/+2 define triangle /n/. /N/-2 triangles are drawn.
+   | TriangleFan
+     -- ^ Draws a connected group of triangles. One triangle is defined for each
+     -- vertex presented after the first two vertices. Vertices 1, /n/+1, and
+     -- /n/+2 define triangle /n/. /N/-2 triangles are drawn.
+   | Quads
+     -- ^ Treats each group of four vertices as an independent quadrilateral.
+     -- Vertices 4/n/-3, 4/n/-2, 4/n/-1, and 4/n/ define quadrilateral /n/.
+     -- /N/\/4 quadrilaterals are drawn.
+   | QuadStrip
+     -- ^ Draws a connected group of quadrilaterals. One quadrilateral is
+     --defined for each pair of vertices presented after the first pair.
+     -- Vertices 2/n/-1, 2/n/, 2/n/+2, and 2/n/+1 define quadrilateral /n/.
+     -- /N/\/2-1 quadrilaterals are drawn. Note that the order in which vertices
+     -- are used to construct a quadrilateral from strip data is different from
+     -- that used with independent data.
+   | Polygon
+     -- ^ Draws a single, convex polygon. Vertices 1 through /N/ define this
+     -- polygon.
+   deriving ( Eq, Ord, Show )
+
+marshalPrimitiveMode :: PrimitiveMode -> GLenum
+marshalPrimitiveMode x = case x of
+   Points -> 0x0
+   Lines -> 0x1
+   LineLoop -> 0x2
+   LineStrip -> 0x3
+   Triangles -> 0x4
+   TriangleStrip -> 0x5
+   TriangleFan -> 0x6
+   Quads -> 0x7
+   QuadStrip -> 0x8
+   Polygon -> 0x9
+
+unmarshalPrimitiveMode :: GLenum -> PrimitiveMode
+unmarshalPrimitiveMode x
+   | x == 0x0 = Points
+   | x == 0x1 = Lines
+   | x == 0x2 = LineLoop
+   | x == 0x3 = LineStrip
+   | x == 0x4 = Triangles
+   | x == 0x5 = TriangleStrip
+   | x == 0x6 = TriangleFan
+   | x == 0x7 = Quads
+   | x == 0x8 = QuadStrip
+   | x == 0x9 = Polygon
+   | otherwise = error ("unmarshalPrimitiveMode: illegal value " ++ show x)
diff --git a/Graphics/Rendering/OGL/GL/QueryUtils.hs b/Graphics/Rendering/OGL/GL/QueryUtils.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/QueryUtils.hs
@@ -0,0 +1,952 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.QueryUtils
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module with utilities to query OpenGL state.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(..),
+   clipPlaneIndexToEnum, lightIndexToEnum,
+   modelviewIndexToEnum, modelviewEnumToIndex,
+   getBoolean1, getBoolean4,
+   getInteger1, getInteger2, getInteger4, getIntegerv,
+   getEnum1,
+   getSizei1,
+   getFloat1, getFloat2, getFloat3, getFloat4, getFloatv,
+   getDouble1, getDouble2, getDouble4, getDoublev
+) where
+
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Marshal.Array ( allocaArray )
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLboolean, GLenum, GLint, GLsizei, GLfloat, GLdouble )
+import Graphics.Rendering.OGL.GL.PeekPoke ( peek1, peek2, peek3, peek4 )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal ( recordInvalidEnum )
+
+--------------------------------------------------------------------------------
+
+data GetPName =
+     GetCurrentColor
+   | GetCurrentIndex
+   | GetCurrentNormal
+   | GetCurrentTextureCoords
+   | GetCurrentRasterColor
+   | GetCurrentRasterSecondaryColor
+   | GetCurrentRasterIndex
+   | GetCurrentRasterTextureCoords
+   | GetCurrentRasterPosition
+   | GetCurrentRasterPositionValid
+   | GetCurrentRasterDistance
+   | GetCurrentMatrixIndex
+   | GetPointSmooth
+   | GetPointSize
+   | GetPointSizeRange
+   | GetPointSizeGranularity
+   | GetLineSmooth
+   | GetLineWidth
+   | GetLineWidthRange
+   | GetLineWidthGranularity
+   | GetLineStipple
+   | GetLineStipplePattern
+   | GetLineStippleRepeat
+   | GetSmoothPointSizeRange
+   | GetSmoothPointSizeGranularity
+   | GetSmoothLineWidthRange
+   | GetSmoothLineWidthGranularity
+   | GetAliasedPointSizeRange
+   | GetAliasedLineWidthRange
+   | GetListMode
+   | GetMaxListNesting
+   | GetListBase
+   | GetListIndex
+   | GetPolygonMode
+   | GetPolygonSmooth
+   | GetPolygonStipple
+   | GetEdgeFlag
+   | GetCullFace
+   | GetCullFaceMode
+   | GetFrontFace
+   | GetLighting
+   | GetLightModelLocalViewer
+   | GetLightModelTwoSide
+   | GetLightModelAmbient
+   | GetShadeModel
+   | GetColorMaterialFace
+   | GetColorMaterialParameter
+   | GetColorMaterial
+   | GetFog
+   | GetFogIndex
+   | GetFogDensity
+   | GetFogStart
+   | GetFogEnd
+   | GetFogMode
+   | GetFogColor
+   | GetFogCoordSrc
+   | GetCurrentFogCoord
+   | GetDepthRange
+   | GetDepthTest
+   | GetDepthWritemask
+   | GetDepthClearValue
+   | GetDepthFunc
+   | GetAccumClearValue
+   | GetStencilTest
+   | GetStencilClearValue
+   | GetStencilFunc
+   | GetStencilValueMask
+   | GetStencilFail
+   | GetStencilPassDepthFail
+   | GetStencilPassDepthPass
+   | GetStencilRef
+   | GetStencilWritemask
+   | GetMatrixMode
+   | GetNormalize
+   | GetViewport
+   | GetModelviewStackDepth
+   | GetProjectionStackDepth
+   | GetTextureStackDepth
+   | GetModelviewMatrix
+   | GetProjectionMatrix
+   | GetTextureMatrix
+   | GetAttribStackDepth
+   | GetClientAttribStackDepth
+   | GetAlphaTest
+   | GetAlphaTestFunc
+   | GetAlphaTestRef
+   | GetDither
+   | GetBlendDst
+   | GetBlendSrc
+   | GetBlend
+   | GetLogicOpMode
+   | GetIndexLogicOp
+   | GetLogicOp
+   | GetColorLogicOp
+   | GetAuxBuffers
+   | GetDrawBuffer
+   | GetReadBuffer
+   | GetScissorBox
+   | GetScissorTest
+   | GetIndexClearValue
+   | GetIndexWritemask
+   | GetColorClearValue
+   | GetColorWritemask
+   | GetIndexMode
+   | GetRGBAMode
+   | GetDoublebuffer
+   | GetStereo
+   | GetRenderMode
+   | GetPerspectiveCorrectionHint
+   | GetPointSmoothHint
+   | GetLineSmoothHint
+   | GetPolygonSmoothHint
+   | GetFogHint
+   | GetGenerateMipmapHint
+   | GetTextureCompressionHint
+   | GetTextureGenS
+   | GetTextureGenT
+   | GetTextureGenR
+   | GetTextureGenQ
+   | GetPixelMapIToISize
+   | GetPixelMapSToSSize
+   | GetPixelMapIToRSize
+   | GetPixelMapIToGSize
+   | GetPixelMapIToBSize
+   | GetPixelMapIToASize
+   | GetPixelMapRToRSize
+   | GetPixelMapGToGSize
+   | GetPixelMapBToBSize
+   | GetPixelMapAToASize
+   | GetUnpackSwapBytes
+   | GetUnpackLSBFirst
+   | GetUnpackRowLength
+   | GetUnpackSkipRows
+   | GetUnpackSkipPixels
+   | GetUnpackAlignment
+   | GetPackSwapBytes
+   | GetPackLSBFirst
+   | GetPackRowLength
+   | GetPackSkipRows
+   | GetPackSkipPixels
+   | GetPackAlignment
+   | GetMapColor
+   | GetMapStencil
+   | GetIndexShift
+   | GetIndexOffset
+   | GetRedScale
+   | GetRedBias
+   | GetZoomX
+   | GetZoomY
+   | GetGreenScale
+   | GetGreenBias
+   | GetBlueScale
+   | GetBlueBias
+   | GetAlphaScale
+   | GetAlphaBias
+   | GetDepthScale
+   | GetDepthBias
+   | GetMaxEvalOrder
+   | GetMaxLights
+   | GetMaxClipPlanes
+   | GetMaxTextureSize
+   | GetMaxPixelMapTable
+   | GetMaxAttribStackDepth
+   | GetMaxModelviewStackDepth
+   | GetMaxNameStackDepth
+   | GetMaxProjectionStackDepth
+   | GetMaxTextureStackDepth
+   | GetMaxViewportDims
+   | GetMaxClientAttribStackDepth
+   | GetSubpixelBits
+   | GetIndexBits
+   | GetRedBits
+   | GetGreenBits
+   | GetBlueBits
+   | GetAlphaBits
+   | GetDepthBits
+   | GetStencilBits
+   | GetAccumRedBits
+   | GetAccumGreenBits
+   | GetAccumBlueBits
+   | GetAccumAlphaBits
+   | GetNameStackDepth
+   | GetAutoNormal
+   | GetMap1Color4
+   | GetMap1Index
+   | GetMap1Normal
+   | GetMap1TextureCoord1
+   | GetMap1TextureCoord2
+   | GetMap1TextureCoord3
+   | GetMap1TextureCoord4
+   | GetMap1Vertex3
+   | GetMap1Vertex4
+   | GetMap2Color4
+   | GetMap2Index
+   | GetMap2Normal
+   | GetMap2TextureCoord1
+   | GetMap2TextureCoord2
+   | GetMap2TextureCoord3
+   | GetMap2TextureCoord4
+   | GetMap2Vertex3
+   | GetMap2Vertex4
+   | GetMap1GridDomain
+   | GetMap1GridSegments
+   | GetMap2GridDomain
+   | GetMap2GridSegments
+   | GetTexture1D
+   | GetTexture2D
+   | GetFeedbackBufferSize
+   | GetFeedbackBufferType
+   | GetSelectionBufferSize
+   | GetPolygonOffsetUnits
+   | GetPolygonOffsetPoint
+   | GetPolygonOffsetLine
+   | GetPolygonOffsetFill
+   | GetPolygonOffsetFactor
+   | GetTextureBinding1D
+   | GetTextureBinding2D
+   | GetTextureBinding3D
+   | GetVertexArray
+   | GetNormalArray
+   | GetColorArray
+   | GetIndexArray
+   | GetTextureCoordArray
+   | GetEdgeFlagArray
+   | GetFogCoordArray
+   | GetSecondaryColorArray
+   | GetMatrixIndexArray
+   | GetVertexArraySize
+   | GetVertexArrayType
+   | GetVertexArrayStride
+   | GetNormalArrayType
+   | GetNormalArrayStride
+   | GetColorArraySize
+   | GetColorArrayType
+   | GetColorArrayStride
+   | GetIndexArrayType
+   | GetIndexArrayStride
+   | GetTextureCoordArraySize
+   | GetTextureCoordArrayType
+   | GetTextureCoordArrayStride
+   | GetEdgeFlagArrayStride
+   | GetFogCoordArrayType
+   | GetFogCoordArrayStride
+   | GetSecondaryColorArraySize
+   | GetSecondaryColorArrayType
+   | GetSecondaryColorArrayStride
+   | GetMatrixIndexArraySize
+   | GetMatrixIndexArrayType
+   | GetMatrixIndexArrayStride
+   | GetClipPlane GLsizei
+   | GetLight GLsizei
+   | GetTransposeModelviewMatrix
+   | GetTransposeProjectionMatrix
+   | GetTransposeTextureMatrix
+   | GetTransposeColorMatrix
+   | GetLightModelColorControl
+   | GetBlendColor
+   | GetBlendEquation
+   | GetBlendEquationAlpha
+   | GetColorTable
+   | GetPostConvolutionColorTable
+   | GetPostColorMatrixColorTable
+   | GetConvolution1D
+   | GetConvolution2D
+   | GetSeparable2D
+   | GetMaxConvolutionWidth
+   | GetMaxConvolutionHeight
+   | GetPostConvolutionRedScale
+   | GetPostConvolutionGreenScale
+   | GetPostConvolutionBlueScale
+   | GetPostConvolutionAlphaScale
+   | GetPostConvolutionRedBias
+   | GetPostConvolutionGreenBias
+   | GetPostConvolutionBlueBias
+   | GetPostConvolutionAlphaBias
+   | GetHistogram
+   | GetMinmax
+   | GetColorSum
+   | GetCurrentSecondaryColor
+   | GetRescaleNormal
+   | GetSharedTexturePalette
+   | GetTexture3DBinding
+   | GetPackSkipImages
+   | GetPackImageHeight
+   | GetUnpackSkipImages
+   | GetUnpackImageHeight
+   | GetTexture3D
+   | GetMax3DTextureSize
+   | GetMaxTextureLODBias
+   | GetMaxTextureMaxAnisotropy
+   | GetMultisample
+   | GetSampleAlphaToCoverage
+   | GetSampleAlphaToOne
+   | GetSampleCoverage
+   | GetSampleBuffers
+   | GetSamples
+   | GetSampleCoverageValue
+   | GetSampleCoverageInvert
+   | GetPointSizeMin
+   | GetPointSizeMax
+   | GetPointFadeThresholdSize
+   | GetPointDistanceAttenuation
+   | GetColorMatrix
+   | GetColorMatrixStackDepth
+   | GetMaxColorMatrixStackDepth
+   | GetPostColorMatrixRedScale
+   | GetPostColorMatrixGreenScale
+   | GetPostColorMatrixBlueScale
+   | GetPostColorMatrixAlphaScale
+   | GetPostColorMatrixRedBias
+   | GetPostColorMatrixGreenBias
+   | GetPostColorMatrixBlueBias
+   | GetPostColorMatrixAlphaBias
+   | GetMaxElementsVertices
+   | GetMaxElementsIndices
+   | GetActiveTexture
+   | GetClientActiveTexture
+   | GetMaxTextureUnits
+   | GetTextureCubeMap
+   | GetMaxCubeMapTextureSize
+   | GetNumCompressedTextureFormats
+   | GetCompressedTextureFormats
+   | GetMaxVertexUnits
+   | GetActiveVertexUnits
+   | GetWeightSumUnity
+   | GetVertexBlend
+   | GetModelview GLsizei
+   | GetCurrentWeight
+   | GetWeightArrayType
+   | GetWeightArrayStride
+   | GetWeightArraySize
+   | GetWeightArray
+   | GetMatrixPalette
+   | GetMaxMatrixPaletteStackDepth
+   | GetMaxPaletteMatrices
+   | GetCurrentPaletteMatrix
+   | GetBlendDstRGB
+   | GetBlendSrcRGB
+   | GetBlendDstAlpha
+   | GetBlendSrcAlpha
+   | GetPackCMYKHint
+   | GetUnpackCMYKHint
+   | GetArrayElementLockFirst
+   | GetArrayElementLockCount
+   | GetMaxShininess
+   | GetMaxSpotExponent
+   | GetFogDistanceMode
+   | GetDepthBounds
+   | GetPrimitiveRestartIndex
+   | GetActiveStencilFace
+   | GetArrayBufferBinding
+   | GetElementArrayBufferBinding
+   | GetVertexArrayBufferBinding
+   | GetNormalArrayBufferBinding
+   | GetColorArrayBufferBinding
+   | GetIndexArrayBufferBinding
+   | GetTextureCoordArrayBufferBinding
+   | GetEdgeFlagArrayBufferBinding
+   | GetSecondaryColorArrayBufferBinding
+   | GetFogCoordArrayBufferBinding
+   | GetTextureBindingCubeMap
+   | GetTextureBindingRectangle
+   | GetCurrentMatrix
+   | GetCurrentMatrixStackDepth
+   | GetMaxCombinedTextureImageUnits
+   | GetMaxDrawBuffers
+   | GetMaxFragmentUniformComponents
+   | GetMaxTextureCoords
+   | GetMaxTextureImageUnits
+   | GetMaxVaryingFloats
+   | GetMaxVertexAttribs
+   | GetMaxVertexTextureImageUnits
+   | GetMaxVertexUniformComponents
+   | GetCurrentProgram
+   | GetPixelPackBufferBinding
+   | GetPixelUnpackBufferBinding
+   | GetDrawBufferN GLsizei
+   -- GetWeightArrayBufferBinding
+   -- GetVertexAttribArrayBufferBinding
+
+marshalGetPName :: GetPName -> Maybe GLenum
+marshalGetPName x = case x of
+   GetCurrentColor -> Just 0xb00
+   GetCurrentIndex -> Just 0xb01
+   GetCurrentNormal -> Just 0xb02
+   GetCurrentTextureCoords -> Just 0xb03
+   GetCurrentRasterColor -> Just 0xb04
+   GetCurrentRasterSecondaryColor -> Just 0x845f
+   GetCurrentRasterIndex -> Just 0xb05
+   GetCurrentRasterTextureCoords -> Just 0xb06
+   GetCurrentRasterPosition -> Just 0xb07
+   GetCurrentRasterPositionValid -> Just 0xb08
+   GetCurrentRasterDistance -> Just 0xb09
+   GetCurrentMatrixIndex -> Just 0x8845
+   GetPointSmooth -> Just 0xb10
+   GetPointSize -> Just 0xb11
+   GetPointSizeRange -> Just 0xb12
+   GetPointSizeGranularity -> Just 0xb13
+   GetLineSmooth -> Just 0xb20
+   GetLineWidth -> Just 0xb21
+   GetLineWidthRange -> Just 0xb22
+   GetLineWidthGranularity -> Just 0xb23
+   GetLineStipple -> Just 0xb24
+   GetLineStipplePattern -> Just 0xb25
+   GetLineStippleRepeat -> Just 0xb26
+   GetSmoothPointSizeRange -> Just 0xb12
+   GetSmoothPointSizeGranularity -> Just 0xb13
+   GetSmoothLineWidthRange -> Just 0xb22
+   GetSmoothLineWidthGranularity -> Just 0xb23
+   GetAliasedPointSizeRange -> Just 0x846d
+   GetAliasedLineWidthRange -> Just 0x846e
+   GetListMode -> Just 0xb30
+   GetMaxListNesting -> Just 0xb31
+   GetListBase -> Just 0xb32
+   GetListIndex -> Just 0xb33
+   GetPolygonMode -> Just 0xb40
+   GetPolygonSmooth -> Just 0xb41
+   GetPolygonStipple -> Just 0xb42
+   GetEdgeFlag -> Just 0xb43
+   GetCullFace -> Just 0xb44
+   GetCullFaceMode -> Just 0xb45
+   GetFrontFace -> Just 0xb46
+   GetLighting -> Just 0xb50
+   GetLightModelLocalViewer -> Just 0xb51
+   GetLightModelTwoSide -> Just 0xb52
+   GetLightModelAmbient -> Just 0xb53
+   GetShadeModel -> Just 0xb54
+   GetColorMaterialFace -> Just 0xb55
+   GetColorMaterialParameter -> Just 0xb56
+   GetColorMaterial -> Just 0xb57
+   GetFog -> Just 0xb60
+   GetFogIndex -> Just 0xb61
+   GetFogDensity -> Just 0xb62
+   GetFogStart -> Just 0xb63
+   GetFogEnd -> Just 0xb64
+   GetFogMode -> Just 0xb65
+   GetFogColor -> Just 0xb66
+   GetFogCoordSrc -> Just 0x8450
+   GetCurrentFogCoord -> Just 0x8453
+   GetDepthRange -> Just 0xb70
+   GetDepthTest -> Just 0xb71
+   GetDepthWritemask -> Just 0xb72
+   GetDepthClearValue -> Just 0xb73
+   GetDepthFunc -> Just 0xb74
+   GetAccumClearValue -> Just 0xb80
+   GetStencilTest -> Just 0xb90
+   GetStencilClearValue -> Just 0xb91
+   GetStencilFunc -> Just 0xb92
+   GetStencilValueMask -> Just 0xb93
+   GetStencilFail -> Just 0xb94
+   GetStencilPassDepthFail -> Just 0xb95
+   GetStencilPassDepthPass -> Just 0xb96
+   GetStencilRef -> Just 0xb97
+   GetStencilWritemask -> Just 0xb98
+   GetMatrixMode -> Just 0xba0
+   GetNormalize -> Just 0xba1
+   GetViewport -> Just 0xba2
+   GetModelviewStackDepth -> Just 0xba3
+   GetProjectionStackDepth -> Just 0xba4
+   GetTextureStackDepth -> Just 0xba5
+   GetModelviewMatrix -> Just 0xba6
+   GetProjectionMatrix -> Just 0xba7
+   GetTextureMatrix -> Just 0xba8
+   GetAttribStackDepth -> Just 0xbb0
+   GetClientAttribStackDepth -> Just 0xbb1
+   GetAlphaTest -> Just 0xbc0
+   GetAlphaTestFunc -> Just 0xbc1
+   GetAlphaTestRef -> Just 0xbc2
+   GetDither -> Just 0xbd0
+   GetBlendDst -> Just 0xbe0
+   GetBlendSrc -> Just 0xbe1
+   GetBlend -> Just 0xbe2
+   GetLogicOpMode -> Just 0xbf0
+   GetIndexLogicOp -> Just 0xbf1
+   GetLogicOp -> Just 0xbf1
+   GetColorLogicOp -> Just 0xbf2
+   GetAuxBuffers -> Just 0xc00
+   GetDrawBuffer -> Just 0xc01
+   GetReadBuffer -> Just 0xc02
+   GetScissorBox -> Just 0xc10
+   GetScissorTest -> Just 0xc11
+   GetIndexClearValue -> Just 0xc20
+   GetIndexWritemask -> Just 0xc21
+   GetColorClearValue -> Just 0xc22
+   GetColorWritemask -> Just 0xc23
+   GetIndexMode -> Just 0xc30
+   GetRGBAMode -> Just 0xc31
+   GetDoublebuffer -> Just 0xc32
+   GetStereo -> Just 0xc33
+   GetRenderMode -> Just 0xc40
+   GetPerspectiveCorrectionHint -> Just 0xc50
+   GetPointSmoothHint -> Just 0xc51
+   GetLineSmoothHint -> Just 0xc52
+   GetPolygonSmoothHint -> Just 0xc53
+   GetFogHint -> Just 0xc54
+   GetGenerateMipmapHint -> Just 0x8192
+   GetTextureCompressionHint -> Just 0x84ef
+   GetTextureGenS -> Just 0xc60
+   GetTextureGenT -> Just 0xc61
+   GetTextureGenR -> Just 0xc62
+   GetTextureGenQ -> Just 0xc63
+   GetPixelMapIToISize -> Just 0xcb0
+   GetPixelMapSToSSize -> Just 0xcb1
+   GetPixelMapIToRSize -> Just 0xcb2
+   GetPixelMapIToGSize -> Just 0xcb3
+   GetPixelMapIToBSize -> Just 0xcb4
+   GetPixelMapIToASize -> Just 0xcb5
+   GetPixelMapRToRSize -> Just 0xcb6
+   GetPixelMapGToGSize -> Just 0xcb7
+   GetPixelMapBToBSize -> Just 0xcb8
+   GetPixelMapAToASize -> Just 0xcb9
+   GetUnpackSwapBytes -> Just 0xcf0
+   GetUnpackLSBFirst -> Just 0xcf1
+   GetUnpackRowLength -> Just 0xcf2
+   GetUnpackSkipRows -> Just 0xcf3
+   GetUnpackSkipPixels -> Just 0xcf4
+   GetUnpackAlignment -> Just 0xcf5
+   GetPackSwapBytes -> Just 0xd00
+   GetPackLSBFirst -> Just 0xd01
+   GetPackRowLength -> Just 0xd02
+   GetPackSkipRows -> Just 0xd03
+   GetPackSkipPixels -> Just 0xd04
+   GetPackAlignment -> Just 0xd05
+   GetMapColor -> Just 0xd10
+   GetMapStencil -> Just 0xd11
+   GetIndexShift -> Just 0xd12
+   GetIndexOffset -> Just 0xd13
+   GetRedScale -> Just 0xd14
+   GetRedBias -> Just 0xd15
+   GetZoomX -> Just 0xd16
+   GetZoomY -> Just 0xd17
+   GetGreenScale -> Just 0xd18
+   GetGreenBias -> Just 0xd19
+   GetBlueScale -> Just 0xd1a
+   GetBlueBias -> Just 0xd1b
+   GetAlphaScale -> Just 0xd1c
+   GetAlphaBias -> Just 0xd1d
+   GetDepthScale -> Just 0xd1e
+   GetDepthBias -> Just 0xd1f
+   GetMaxEvalOrder -> Just 0xd30
+   GetMaxLights -> Just 0xd31
+   GetMaxClipPlanes -> Just 0xd32
+   GetMaxTextureSize -> Just 0xd33
+   GetMaxPixelMapTable -> Just 0xd34
+   GetMaxAttribStackDepth -> Just 0xd35
+   GetMaxModelviewStackDepth -> Just 0xd36
+   GetMaxNameStackDepth -> Just 0xd37
+   GetMaxProjectionStackDepth -> Just 0xd38
+   GetMaxTextureStackDepth -> Just 0xd39
+   GetMaxViewportDims -> Just 0xd3a
+   GetMaxClientAttribStackDepth -> Just 0xd3b
+   GetSubpixelBits -> Just 0xd50
+   GetIndexBits -> Just 0xd51
+   GetRedBits -> Just 0xd52
+   GetGreenBits -> Just 0xd53
+   GetBlueBits -> Just 0xd54
+   GetAlphaBits -> Just 0xd55
+   GetDepthBits -> Just 0xd56
+   GetStencilBits -> Just 0xd57
+   GetAccumRedBits -> Just 0xd58
+   GetAccumGreenBits -> Just 0xd59
+   GetAccumBlueBits -> Just 0xd5a
+   GetAccumAlphaBits -> Just 0xd5b
+   GetNameStackDepth -> Just 0xd70
+   GetAutoNormal -> Just 0xd80
+   GetMap1Color4 -> Just 0xd90
+   GetMap1Index -> Just 0xd91
+   GetMap1Normal -> Just 0xd92
+   GetMap1TextureCoord1 -> Just 0xd93
+   GetMap1TextureCoord2 -> Just 0xd94
+   GetMap1TextureCoord3 -> Just 0xd95
+   GetMap1TextureCoord4 -> Just 0xd96
+   GetMap1Vertex3 -> Just 0xd97
+   GetMap1Vertex4 -> Just 0xd98
+   GetMap2Color4 -> Just 0xdb0
+   GetMap2Index -> Just 0xdb1
+   GetMap2Normal -> Just 0xdb2
+   GetMap2TextureCoord1 -> Just 0xdb3
+   GetMap2TextureCoord2 -> Just 0xdb4
+   GetMap2TextureCoord3 -> Just 0xdb5
+   GetMap2TextureCoord4 -> Just 0xdb6
+   GetMap2Vertex3 -> Just 0xdb7
+   GetMap2Vertex4 -> Just 0xdb8
+   GetMap1GridDomain -> Just 0xdd0
+   GetMap1GridSegments -> Just 0xdd1
+   GetMap2GridDomain -> Just 0xdd2
+   GetMap2GridSegments -> Just 0xdd3
+   GetTexture1D -> Just 0xde0
+   GetTexture2D -> Just 0xde1
+   GetFeedbackBufferSize -> Just 0xdf1
+   GetFeedbackBufferType -> Just 0xdf2
+   GetSelectionBufferSize -> Just 0xdf4
+   GetPolygonOffsetUnits -> Just 0x2a00
+   GetPolygonOffsetPoint -> Just 0x2a01
+   GetPolygonOffsetLine -> Just 0x2a02
+   GetPolygonOffsetFill -> Just 0x8037
+   GetPolygonOffsetFactor -> Just 0x8038
+   GetTextureBinding1D -> Just 0x8068
+   GetTextureBinding2D -> Just 0x8069
+   GetTextureBinding3D -> Just 0x806a
+   GetVertexArray -> Just 0x8074
+   GetNormalArray -> Just 0x8075
+   GetColorArray -> Just 0x8076
+   GetIndexArray -> Just 0x8077
+   GetTextureCoordArray -> Just 0x8078
+   GetEdgeFlagArray -> Just 0x8079
+   GetFogCoordArray -> Just 0x8457
+   GetSecondaryColorArray -> Just 0x845e
+   GetMatrixIndexArray -> Just 0x8844
+   GetVertexArraySize -> Just 0x807a
+   GetVertexArrayType -> Just 0x807b
+   GetVertexArrayStride -> Just 0x807c
+   GetNormalArrayType -> Just 0x807e
+   GetNormalArrayStride -> Just 0x807f
+   GetColorArraySize -> Just 0x8081
+   GetColorArrayType -> Just 0x8082
+   GetColorArrayStride -> Just 0x8083
+   GetIndexArrayType -> Just 0x8085
+   GetIndexArrayStride -> Just 0x8086
+   GetTextureCoordArraySize -> Just 0x8088
+   GetTextureCoordArrayType -> Just 0x8089
+   GetTextureCoordArrayStride -> Just 0x808a
+   GetEdgeFlagArrayStride -> Just 0x808c
+   GetFogCoordArrayType -> Just 0x8454
+   GetFogCoordArrayStride -> Just 0x8455
+   GetSecondaryColorArraySize -> Just 0x845a
+   GetSecondaryColorArrayType -> Just 0x845b
+   GetSecondaryColorArrayStride -> Just 0x845c
+   GetMatrixIndexArraySize -> Just 0x8846
+   GetMatrixIndexArrayType -> Just 0x8847
+   GetMatrixIndexArrayStride -> Just 0x8848
+   GetClipPlane i -> clipPlaneIndexToEnum i
+   GetLight i -> lightIndexToEnum i
+   GetTransposeModelviewMatrix -> Just 0x84e3
+   GetTransposeProjectionMatrix -> Just 0x84e4
+   GetTransposeTextureMatrix -> Just 0x84e5
+   GetTransposeColorMatrix -> Just 0x84e6
+   GetLightModelColorControl -> Just 0x81f8
+   GetBlendColor -> Just 0x8005
+   GetBlendEquation -> Just 0x8009
+   GetBlendEquationAlpha -> Just 0x883d
+   GetColorTable -> Just 0x80d0
+   GetPostConvolutionColorTable -> Just 0x80d1
+   GetPostColorMatrixColorTable -> Just 0x80d2
+   GetConvolution1D -> Just 0x8010
+   GetConvolution2D -> Just 0x8011
+   GetSeparable2D -> Just 0x8012
+   GetMaxConvolutionWidth -> Just 0x801a
+   GetMaxConvolutionHeight -> Just 0x801b
+   GetPostConvolutionRedScale -> Just 0x801c
+   GetPostConvolutionGreenScale -> Just 0x801d
+   GetPostConvolutionBlueScale -> Just 0x801e
+   GetPostConvolutionAlphaScale -> Just 0x801f
+   GetPostConvolutionRedBias -> Just 0x8020
+   GetPostConvolutionGreenBias -> Just 0x8021
+   GetPostConvolutionBlueBias -> Just 0x8022
+   GetPostConvolutionAlphaBias -> Just 0x8023
+   GetHistogram -> Just 0x8024
+   GetMinmax -> Just 0x802e
+   GetColorSum -> Just 0x8458
+   GetCurrentSecondaryColor -> Just 0x8459
+   GetRescaleNormal -> Just 0x803a
+   GetSharedTexturePalette -> Just 0x81fb
+   GetTexture3DBinding -> Just 0x806a
+   GetPackSkipImages -> Just 0x806b
+   GetPackImageHeight -> Just 0x806c
+   GetUnpackSkipImages -> Just 0x806d
+   GetUnpackImageHeight -> Just 0x806e
+   GetTexture3D -> Just 0x806f
+   GetMax3DTextureSize -> Just 0x8073
+   GetMaxTextureLODBias -> Just 0x84fd
+   GetMaxTextureMaxAnisotropy -> Just 0x84ff
+   GetMultisample -> Just 0x809d
+   GetSampleAlphaToCoverage -> Just 0x809e
+   GetSampleAlphaToOne -> Just 0x809f
+   GetSampleCoverage -> Just 0x80a0
+   GetSampleBuffers -> Just 0x80a8
+   GetSamples -> Just 0x80a9
+   GetSampleCoverageValue -> Just 0x80aa
+   GetSampleCoverageInvert -> Just 0x80ab
+   GetPointSizeMin -> Just 0x8126
+   GetPointSizeMax -> Just 0x8127
+   GetPointFadeThresholdSize -> Just 0x8128
+   GetPointDistanceAttenuation -> Just 0x8129
+   GetColorMatrix -> Just 0x80b1
+   GetColorMatrixStackDepth -> Just 0x80b2
+   GetMaxColorMatrixStackDepth -> Just 0x80b3
+   GetPostColorMatrixRedScale -> Just 0x80b4
+   GetPostColorMatrixGreenScale -> Just 0x80b5
+   GetPostColorMatrixBlueScale -> Just 0x80b6
+   GetPostColorMatrixAlphaScale -> Just 0x80b7
+   GetPostColorMatrixRedBias -> Just 0x80b8
+   GetPostColorMatrixGreenBias -> Just 0x80b9
+   GetPostColorMatrixBlueBias -> Just 0x80ba
+   GetPostColorMatrixAlphaBias -> Just 0x80bb
+   GetMaxElementsVertices -> Just 0x80e8
+   GetMaxElementsIndices -> Just 0x80e9
+   GetActiveTexture -> Just 0x84e0
+   GetClientActiveTexture -> Just 0x84e1
+   GetMaxTextureUnits -> Just 0x84e2
+   GetTextureCubeMap -> Just 0x8513
+   GetMaxCubeMapTextureSize -> Just 0x851c
+   GetNumCompressedTextureFormats -> Just 0x86a2
+   GetCompressedTextureFormats -> Just 0x86a3
+   GetMaxVertexUnits -> Just 0x86a4
+   GetActiveVertexUnits -> Just 0x86a5
+   GetWeightSumUnity -> Just 0x86a6
+   GetVertexBlend -> Just 0x86a7
+   GetModelview i -> modelviewIndexToEnum i
+   GetCurrentWeight -> Just 0x86a8
+   GetWeightArrayType -> Just 0x86a9
+   GetWeightArrayStride -> Just 0x86aa
+   GetWeightArraySize -> Just 0x86ab
+   GetWeightArray -> Just 0x86ad
+   GetMatrixPalette -> Just 0x8840
+   GetMaxMatrixPaletteStackDepth -> Just 0x8841
+   GetMaxPaletteMatrices -> Just 0x8842
+   GetCurrentPaletteMatrix -> Just 0x8843
+   GetBlendDstRGB -> Just 0x80c8
+   GetBlendSrcRGB -> Just 0x80c9
+   GetBlendDstAlpha -> Just 0x80ca
+   GetBlendSrcAlpha -> Just 0x80cb
+   GetPackCMYKHint -> Just 0x800e
+   GetUnpackCMYKHint -> Just 0x800f
+   GetArrayElementLockFirst -> Just 0x81a8
+   GetArrayElementLockCount -> Just 0x81a9
+   GetMaxShininess -> Just 0x8504
+   GetMaxSpotExponent -> Just 0x8505
+   GetFogDistanceMode -> Just 0x855a
+   GetDepthBounds -> Just 0x8891
+   GetPrimitiveRestartIndex -> Just 0x8559
+   GetActiveStencilFace -> Just 0x8911
+   GetArrayBufferBinding -> Just 0x8894
+   GetElementArrayBufferBinding -> Just 0x8895
+   GetVertexArrayBufferBinding -> Just 0x8896
+   GetNormalArrayBufferBinding -> Just 0x8897
+   GetColorArrayBufferBinding -> Just 0x8898
+   GetIndexArrayBufferBinding -> Just 0x8899
+   GetTextureCoordArrayBufferBinding -> Just 0x889a
+   GetEdgeFlagArrayBufferBinding -> Just 0x889b
+   GetSecondaryColorArrayBufferBinding -> Just 0x889c
+   GetFogCoordArrayBufferBinding -> Just 0x889d
+   GetTextureBindingCubeMap -> Just 0x8514
+   GetTextureBindingRectangle -> Just 0x84f6
+   GetCurrentMatrix -> Just 0x8641
+   GetCurrentMatrixStackDepth -> Just 0x8640
+   GetMaxCombinedTextureImageUnits -> Just 0x8b4d
+   GetMaxDrawBuffers -> Just 0x8824
+   GetMaxFragmentUniformComponents -> Just 0x8b49
+   GetMaxTextureCoords -> Just 0x8871
+   GetMaxTextureImageUnits -> Just 0x8872
+   GetMaxVaryingFloats -> Just 0x8b4b
+   GetMaxVertexAttribs -> Just 0x8869
+   GetMaxVertexTextureImageUnits -> Just 0x8b4c
+   GetMaxVertexUniformComponents -> Just 0x8b4a
+   GetCurrentProgram -> Just 0x8b8d
+   GetPixelPackBufferBinding -> Just 0x88ed
+   GetPixelUnpackBufferBinding -> Just 0x88EF
+   GetDrawBufferN i -> drawBufferIndexToEnum i
+   -- GetWeightArrayBufferBinding -> Just 0x889e
+   -- GetVertexAttribArrayBufferBinding -> Just 0x889f
+
+--------------------------------------------------------------------------------
+
+-- 0x3000 through 0x3FFF are reserved for clip planes
+
+clipPlaneIndexToEnum :: GLsizei -> Maybe GLenum
+clipPlaneIndexToEnum i
+   | 0 <= i && i <= 0xFFF = Just (0x3000 + fromIntegral i)
+   | otherwise = Nothing
+
+--------------------------------------------------------------------------------
+
+-- 0x4000 through 0x4FFF are reserved for light numbers
+
+lightIndexToEnum :: GLsizei -> Maybe GLenum
+lightIndexToEnum i
+   | 0 <= i && i <= 0xFFF = Just (0x4000 + fromIntegral i)
+   | otherwise = Nothing
+
+--------------------------------------------------------------------------------
+
+-- 0x1700, 0x850a, and 0x8722 through 0x873f are reserved for modelview matrices
+
+modelviewIndexToEnum :: GLsizei -> Maybe GLenum
+modelviewIndexToEnum 0 = Just 0x1700
+modelviewIndexToEnum 1 = Just 0x850a
+modelviewIndexToEnum i
+   | 2 <= i && i <= 31 = Just (0x8720 + fromIntegral i)
+   | otherwise = Nothing
+
+modelviewEnumToIndex :: GLenum -> Maybe GLsizei
+modelviewEnumToIndex x
+   | x == 0x1700 = Just 0
+   | x == 0x850a = Just 1
+   | 0x8722 <= x && x <= 0x873f = Just (fromIntegral x - 0x8720)
+   | otherwise = Nothing
+
+--------------------------------------------------------------------------------
+
+-- 0x8825 through 0x8834 are reserved for draw buffers
+
+drawBufferIndexToEnum :: GLsizei -> Maybe GLenum
+drawBufferIndexToEnum i
+   | 0 <= i && i <= 15 = Just (0x8825 + fromIntegral i)
+   | otherwise = Nothing
+
+--------------------------------------------------------------------------------
+
+getBoolean1 :: (GLboolean -> a) -> GetPName -> IO a
+getBoolean1 f n = alloca $ \buf -> do
+   getBooleanv n buf
+   peek1 f buf
+
+getBoolean4 :: (GLboolean -> GLboolean -> GLboolean -> GLboolean -> a)
+            -> GetPName -> IO a
+getBoolean4 f n = allocaArray 4 $ \buf -> do
+   getBooleanv n buf
+   peek4 f buf
+
+foreign import CALLCONV unsafe "glGetBooleanv" glGetBooleanv ::
+   GLenum -> Ptr GLboolean -> IO ()
+
+getBooleanv :: GetPName -> Ptr GLboolean -> IO ()
+getBooleanv = makeGetter glGetBooleanv
+
+{-# INLINE makeGetter #-}
+makeGetter :: (GLenum -> Ptr a -> IO ()) -> GetPName -> Ptr a -> IO ()
+makeGetter f = maybe (const recordInvalidEnum) f . marshalGetPName
+
+--------------------------------------------------------------------------------
+
+getInteger1 :: (GLint -> a) -> GetPName -> IO a
+getInteger1 f n = alloca $ \buf -> do
+   getIntegerv n buf
+   peek1 f buf
+
+getInteger2 :: (GLint -> GLint -> a) -> GetPName -> IO a
+getInteger2 f n = allocaArray 2 $ \buf -> do
+   getIntegerv n buf
+   peek2 f buf
+
+getInteger4 :: (GLint -> GLint -> GLint -> GLint -> a) -> GetPName -> IO a
+getInteger4 f n = allocaArray 4 $ \buf -> do
+   getIntegerv n buf
+   peek4 f buf
+
+getIntegerv :: GetPName -> Ptr GLint -> IO ()
+getIntegerv = maybe (const recordInvalidEnum) glGetIntegerv . marshalGetPName
+
+foreign import CALLCONV unsafe "glGetIntegerv" glGetIntegerv ::
+   GLenum -> Ptr GLint -> IO ()
+
+--------------------------------------------------------------------------------
+
+getEnum1 :: (GLenum -> a) -> GetPName -> IO a
+getEnum1 f = getInteger1 (f . fromIntegral)
+
+getSizei1 :: (GLsizei -> a) -> GetPName -> IO a
+getSizei1 f = getInteger1 (f . fromIntegral)
+
+--------------------------------------------------------------------------------
+
+getFloat1 :: (GLfloat -> a) -> GetPName -> IO a
+getFloat1 f n = alloca $ \buf -> do
+   getFloatv n buf
+   peek1 f buf
+
+getFloat2 :: (GLfloat -> GLfloat -> a) -> GetPName -> IO a
+getFloat2 f n = allocaArray 2 $ \buf -> do
+   getFloatv n buf
+   peek2 f buf
+
+getFloat3 :: (GLfloat -> GLfloat -> GLfloat -> a) -> GetPName -> IO a
+getFloat3 f n = allocaArray 3 $ \buf -> do
+   getFloatv n buf
+   peek3 f buf
+
+getFloat4 ::
+   (GLfloat -> GLfloat -> GLfloat -> GLfloat -> a) -> GetPName -> IO a
+getFloat4 f n = allocaArray 4 $ \buf -> do
+   getFloatv n buf
+   peek4 f buf
+
+getFloatv :: GetPName -> Ptr GLfloat -> IO ()
+getFloatv = maybe (const recordInvalidEnum) glGetFloatv . marshalGetPName
+
+foreign import CALLCONV unsafe "glGetFloatv" glGetFloatv ::
+   GLenum -> Ptr GLfloat -> IO ()
+
+--------------------------------------------------------------------------------
+
+getDouble1 :: (GLdouble -> a) -> GetPName -> IO a
+getDouble1 f n = alloca $ \buf -> do
+   getDoublev n buf
+   peek1 f buf
+
+getDouble2 :: (GLdouble -> GLdouble -> a) -> GetPName -> IO a
+getDouble2 f n = allocaArray 2 $ \buf -> do
+   getDoublev n buf
+   peek2 f buf
+
+getDouble4 ::
+   (GLdouble -> GLdouble -> GLdouble -> GLdouble -> a) -> GetPName -> IO a
+getDouble4 f n = allocaArray 4 $ \buf -> do
+   getDoublev n buf
+   peek4 f buf
+
+getDoublev :: GetPName -> Ptr GLdouble -> IO ()
+getDoublev = maybe (const recordInvalidEnum) glGetDoublev . marshalGetPName
+
+foreign import CALLCONV unsafe "glGetDoublev" glGetDoublev ::
+   GLenum -> Ptr GLdouble -> IO ()
diff --git a/Graphics/Rendering/OGL/GL/RasterPos.hs b/Graphics/Rendering/OGL/GL/RasterPos.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/RasterPos.hs
@@ -0,0 +1,311 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.RasterPos
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 2.13 (Current Raster Position) of the
+-- OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.RasterPos (
+   currentRasterPosition, RasterPosComponent, RasterPos(..),
+   WindowPosComponent, WindowPos(..),
+   currentRasterDistance, currentRasterColor, currentRasterSecondaryColor,
+   currentRasterIndex, currentRasterTexCoords, currentRasterPositionValid,
+   rasterPositionUnclipped
+) where
+
+import Data.Int
+import Foreign.Ptr ( Ptr, castPtr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLshort, GLint, GLfloat, GLdouble, Capability )
+import Graphics.Rendering.OGL.GL.GLboolean ( unmarshalGLboolean )
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapRasterPositionUnclipped), makeCapability )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetCurrentRasterPosition,GetCurrentRasterDistance,
+            GetCurrentRasterColor,GetCurrentRasterSecondaryColor,
+            GetCurrentRasterIndex,GetCurrentRasterTextureCoords,
+            GetCurrentRasterPositionValid),
+   getBoolean1, getInteger1, getFloat1, getFloat4 )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.VertexSpec (
+   Vertex2(..), Vertex3(..), Vertex4(..), TexCoord4(..),
+   Color4(..), Index1(..) )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+#include "HsOpenGLTypes.h"
+
+--------------------------------------------------------------------------------
+
+currentRasterPosition :: StateVar (Vertex4 GLfloat)
+currentRasterPosition =
+   makeStateVar (getFloat4 Vertex4 GetCurrentRasterPosition) (runGL . rasterPos)
+
+--------------------------------------------------------------------------------
+
+class RasterPosComponent a where
+   rasterPos2 :: a -> a -> GL ()
+   rasterPos3 :: a -> a -> a -> GL ()
+   rasterPos4 :: a -> a -> a -> a -> GL ()
+
+   rasterPos2v :: Ptr a -> GL ()
+   rasterPos3v :: Ptr a -> GL ()
+   rasterPos4v :: Ptr a -> GL ()
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glRasterPos2s" glRasterPos2s ::
+   GLshort -> GLshort -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos3s" glRasterPos3s ::
+   GLshort -> GLshort -> GLshort -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos4s" glRasterPos4s ::
+   GLshort -> GLshort -> GLshort -> GLshort -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos2sv" glRasterPos2sv ::
+   Ptr GLshort -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos3sv" glRasterPos3sv ::
+   Ptr GLshort -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos4sv" glRasterPos4sv ::
+   Ptr GLshort -> GL ()
+
+instance RasterPosComponent GLshort_ where
+   rasterPos2 = glRasterPos2s
+   rasterPos3 = glRasterPos3s
+   rasterPos4 = glRasterPos4s
+
+   rasterPos2v = glRasterPos2sv
+   rasterPos3v = glRasterPos3sv
+   rasterPos4v = glRasterPos4sv
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glRasterPos2i" glRasterPos2i ::
+   GLint -> GLint -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos3i" glRasterPos3i ::
+   GLint -> GLint -> GLint -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos4i" glRasterPos4i ::
+   GLint -> GLint -> GLint -> GLint -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos2iv" glRasterPos2iv ::
+   Ptr GLint -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos3iv" glRasterPos3iv ::
+   Ptr GLint -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos4iv" glRasterPos4iv ::
+   Ptr GLint -> GL ()
+
+instance RasterPosComponent GLint_ where
+   rasterPos2 = glRasterPos2i
+   rasterPos3 = glRasterPos3i
+   rasterPos4 = glRasterPos4i
+
+   rasterPos2v = glRasterPos2iv
+   rasterPos3v = glRasterPos3iv
+   rasterPos4v = glRasterPos4iv
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glRasterPos2f" glRasterPos2f ::
+   GLfloat -> GLfloat -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos3f" glRasterPos3f ::
+   GLfloat -> GLfloat -> GLfloat -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos4f" glRasterPos4f ::
+   GLfloat -> GLfloat -> GLfloat -> GLfloat -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos2fv" glRasterPos2fv ::
+   Ptr GLfloat -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos3fv" glRasterPos3fv ::
+   Ptr GLfloat -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos4fv" glRasterPos4fv ::
+   Ptr GLfloat -> GL ()
+
+instance RasterPosComponent GLfloat_ where
+   rasterPos2 = glRasterPos2f
+   rasterPos3 = glRasterPos3f
+   rasterPos4 = glRasterPos4f
+
+   rasterPos2v = glRasterPos2fv
+   rasterPos3v = glRasterPos3fv
+   rasterPos4v = glRasterPos4fv
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glRasterPos2d" glRasterPos2d ::
+   GLdouble -> GLdouble -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos3d" glRasterPos3d ::
+   GLdouble -> GLdouble -> GLdouble -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos4d" glRasterPos4d ::
+   GLdouble -> GLdouble -> GLdouble -> GLdouble -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos2dv" glRasterPos2dv ::
+   Ptr GLdouble -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos3dv" glRasterPos3dv ::
+   Ptr GLdouble -> GL ()
+
+foreign import CALLCONV unsafe "glRasterPos4dv" glRasterPos4dv ::
+   Ptr GLdouble -> GL ()
+
+instance RasterPosComponent GLdouble_ where
+   rasterPos2 = glRasterPos2d
+   rasterPos3 = glRasterPos3d
+   rasterPos4 = glRasterPos4d
+
+   rasterPos2v = glRasterPos2dv
+   rasterPos3v = glRasterPos3dv
+   rasterPos4v = glRasterPos4dv
+
+--------------------------------------------------------------------------------
+
+class RasterPos a where
+   rasterPos  ::     a -> GL ()
+   rasterPosv :: Ptr a -> GL ()
+
+instance RasterPosComponent a => RasterPos (Vertex2 a) where
+   rasterPos (Vertex2 x y) = rasterPos2 x y
+   rasterPosv = rasterPos2v . (castPtr :: Ptr (Vertex2 b) -> Ptr b)
+
+instance RasterPosComponent a => RasterPos (Vertex3 a) where
+   rasterPos (Vertex3 x y z) = rasterPos3 x y z
+   rasterPosv = rasterPos3v . (castPtr :: Ptr (Vertex3 b) -> Ptr b)
+
+instance RasterPosComponent a => RasterPos (Vertex4 a) where
+   rasterPos (Vertex4 x y z w) = rasterPos4 x y z w
+   rasterPosv = rasterPos4v . (castPtr :: Ptr (Vertex4 b) -> Ptr b)
+
+--------------------------------------------------------------------------------
+
+class WindowPosComponent a where
+   windowPos2 :: a -> a -> GL ()
+   windowPos3 :: a -> a -> a -> GL ()
+
+   windowPos2v :: Ptr a -> GL ()
+   windowPos3v :: Ptr a -> GL ()
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos2sARB,GLshort -> GLshort -> GL ())
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos3sARB,GLshort -> GLshort -> GLshort -> GL ())
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos2svARB,Ptr GLshort -> GL ())
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos3svARB,Ptr GLshort -> GL ())
+
+instance WindowPosComponent GLshort_ where
+   windowPos2 = glWindowPos2sARB
+   windowPos3 = glWindowPos3sARB
+
+   windowPos2v = glWindowPos2svARB
+   windowPos3v = glWindowPos3svARB
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos2iARB,GLint -> GLint -> GL ())
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos3iARB,GLint -> GLint -> GLint -> GL ())
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos2ivARB,Ptr GLint -> GL ())
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos3ivARB,Ptr GLint -> GL ())
+
+instance WindowPosComponent GLint_ where
+   windowPos2 = glWindowPos2iARB
+   windowPos3 = glWindowPos3iARB
+
+   windowPos2v = glWindowPos2ivARB
+   windowPos3v = glWindowPos3ivARB
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos2fARB,GLfloat -> GLfloat -> GL ())
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos3fARB,GLfloat -> GLfloat -> GLfloat -> GL ())
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos2fvARB,Ptr GLfloat -> GL ())
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos3fvARB,Ptr GLfloat -> GL ())
+
+instance WindowPosComponent GLfloat_ where
+   windowPos2 = glWindowPos2fARB
+   windowPos3 = glWindowPos3fARB
+
+   windowPos2v = glWindowPos2fvARB
+   windowPos3v = glWindowPos3fvARB
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos2dARB,GLdouble -> GLdouble -> GL ())
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos3dARB,GLdouble -> GLdouble -> GLdouble -> GL ())
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos2dvARB,Ptr GLdouble -> GL ())
+EXTENSION_ENTRY("GL_ARB_window_pos or OpenGL 1.4",glWindowPos3dvARB,Ptr GLdouble -> GL ())
+
+instance WindowPosComponent GLdouble_ where
+   windowPos2 = glWindowPos2dARB
+   windowPos3 = glWindowPos3dARB
+
+   windowPos2v = glWindowPos2dvARB
+   windowPos3v = glWindowPos3dvARB
+--------------------------------------------------------------------------------
+
+
+class WindowPos a where
+   windowPos  ::     a -> GL ()
+   windowPosv :: Ptr a -> GL ()
+
+instance WindowPosComponent a => WindowPos (Vertex2 a) where
+   windowPos (Vertex2 x y) = windowPos2 x y
+   windowPosv = windowPos2v . (castPtr :: Ptr (Vertex2 b) -> Ptr b)
+
+instance WindowPosComponent a => WindowPos (Vertex3 a) where
+   windowPos (Vertex3 x y z) = windowPos3 x y z
+   windowPosv = windowPos3v . (castPtr :: Ptr (Vertex3 b) -> Ptr b)
+
+--------------------------------------------------------------------------------
+
+currentRasterDistance :: GettableStateVar GLfloat
+currentRasterDistance =
+   makeGettableStateVar (getFloat1 id GetCurrentRasterDistance)
+
+currentRasterColor :: GettableStateVar (Color4 GLfloat)
+currentRasterColor =
+   makeGettableStateVar (getFloat4 Color4 GetCurrentRasterColor)
+
+currentRasterSecondaryColor :: GettableStateVar (Color4 GLfloat)
+currentRasterSecondaryColor =
+   makeGettableStateVar (getFloat4 Color4 GetCurrentRasterSecondaryColor)
+
+currentRasterIndex :: GettableStateVar (Index1 GLint)
+currentRasterIndex =
+   makeGettableStateVar (getInteger1 Index1 GetCurrentRasterIndex)
+
+currentRasterTexCoords :: GettableStateVar (TexCoord4 GLfloat)
+currentRasterTexCoords =
+   makeGettableStateVar (getFloat4 TexCoord4 GetCurrentRasterTextureCoords)
+
+currentRasterPositionValid :: GettableStateVar Bool
+currentRasterPositionValid =
+   makeGettableStateVar
+      (getBoolean1 unmarshalGLboolean GetCurrentRasterPositionValid)
+
+--------------------------------------------------------------------------------
+
+rasterPositionUnclipped :: StateVar Capability
+rasterPositionUnclipped = makeCapability CapRasterPositionUnclipped
diff --git a/Graphics/Rendering/OGL/GL/ReadCopyPixels.hs b/Graphics/Rendering/OGL/GL/ReadCopyPixels.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/ReadCopyPixels.hs
@@ -0,0 +1,78 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.ReadCopyPixels
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 4.3 (Drawing, Reading, and Copying Pixels)
+-- of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.ReadCopyPixels (
+   -- * Reading Pixels
+   readPixels, readBuffer,
+
+   -- * Copying Pixels
+   PixelCopyType(..), copyPixels
+) where
+
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum, GLint, GLsizei )
+import Graphics.Rendering.OGL.GL.BufferMode (
+   marshalBufferMode, unmarshalBufferMode )
+import Graphics.Rendering.OGL.GL.Framebuffer ( BufferMode(..) )
+import Graphics.Rendering.OGL.GL.CoordTrans ( Position(..), Size(..) )
+import Graphics.Rendering.OGL.GL.PixelData ( withPixelData )
+import Graphics.Rendering.OGL.GL.PixelRectangles ( PixelData )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetReadBuffer), getEnum1 )
+import Graphics.Rendering.OGL.GL.StateVar ( StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal ( recordInvalidValue )
+
+--------------------------------------------------------------------------------
+
+readPixels :: Position -> Size -> PixelData a -> GL ()
+readPixels (Position x y) (Size w h) pd =
+   withPixelData pd $ glReadPixels x y w h
+
+foreign import CALLCONV unsafe "glReadPixels" glReadPixels ::
+   GLint -> GLint -> GLsizei -> GLsizei -> GLenum -> GLenum -> Ptr a -> GL ()
+
+--------------------------------------------------------------------------------
+
+readBuffer :: StateVar BufferMode
+readBuffer =
+   makeStateVar
+      (getEnum1 unmarshalBufferMode GetReadBuffer)
+      (maybe recordInvalidValue glReadBuffer . marshalBufferMode)
+
+foreign import CALLCONV unsafe "glReadBuffer" glReadBuffer :: GLenum -> IO ()
+
+--------------------------------------------------------------------------------
+
+data PixelCopyType =
+     CopyColor
+   | CopyDepth
+   | CopyStencil
+   deriving ( Eq, Ord, Show )
+
+marshalPixelCopyType :: PixelCopyType -> GLenum
+marshalPixelCopyType x = case x of
+   CopyColor -> 0x1800
+   CopyDepth -> 0x1801
+   CopyStencil -> 0x1802
+
+--------------------------------------------------------------------------------
+
+copyPixels :: Position -> Size -> PixelCopyType -> GL ()
+copyPixels (Position x y) (Size w h) t =
+   glCopyPixels x y w h (marshalPixelCopyType t)
+
+foreign import CALLCONV unsafe "glCopyPixels" glCopyPixels ::
+   GLint -> GLint -> GLsizei -> GLsizei -> GLenum -> GL ()
diff --git a/Graphics/Rendering/OGL/GL/Rectangles.hs b/Graphics/Rendering/OGL/GL/Rectangles.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Rectangles.hs
@@ -0,0 +1,106 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Rectangles
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 2.10 (Rectangles) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Rectangles (
+   Rect(..)
+) where
+
+import Data.Int
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLshort, GLint, GLfloat, GLdouble )
+import Graphics.Rendering.OGL.GL.VertexSpec ( Vertex2(..) )
+#ifdef __HADDOCK__
+import Graphics.Rendering.OGL.GL.BeginEnd ( PrimitiveMode(Polygon) )
+#endif
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+#include "HsOpenGLTypes.h"
+
+--------------------------------------------------------------------------------
+
+-- | 'rect' and 'rectv' support efficient specification of rectangles as two
+-- corner points. Each rectangle command takes four arguments, organized either
+-- as two consecutive pairs of (/x/, /y/) coordinates, or as two pointers to
+-- arrays, each containing an (/x/, /y/) pair. The resulting rectangle is
+-- defined in the /z/ = 0 plane.
+--
+-- @'rect' ('Vertex2' x1 y1) ('Vertex2' x2, y2)@ is exactly equivalent to the
+-- following sequence:
+--
+-- @
+--    'Graphics.Rendering.OGL.GL.BeginEnd.renderPrimitive' 'Graphics.Rendering.OGL.GL.BeginEnd.Polygon' $ do
+--        'Graphics.Rendering.OGL.GL.VertexSpec.vertex' ('Vertex2' x1 y1)
+--        'Graphics.Rendering.OGL.GL.VertexSpec.vertex' ('Vertex2' x2 y1)
+--        'Graphics.Rendering.OGL.GL.VertexSpec.vertex' ('Vertex2' x2 y2)
+--        'Graphics.Rendering.OGL.GL.VertexSpec.vertex' ('Vertex2' x1 y2)
+-- @
+--
+-- Note that if the second vertex is above and to the right of the first vertex,
+-- the rectangle is constructed with a counterclockwise winding.
+
+class Rect a where
+   rect  :: Vertex2 a -> Vertex2 a -> GL ()
+   rectv :: Ptr     a -> Ptr     a -> GL ()
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glRects" glRects ::
+   GLshort -> GLshort -> GLshort -> GLshort -> IO ()
+
+foreign import CALLCONV unsafe "glRectsv" glRectsv ::
+   Ptr GLshort -> Ptr GLshort -> IO ()
+
+instance Rect GLshort_ where
+   rect (Vertex2 x1 y1) (Vertex2 x2 y2) = liftIO $ glRects x1 y1 x2 y2
+   rectv ptr1 ptr2 = liftIO $ glRectsv ptr1 ptr2
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glRecti" glRecti ::
+   GLint -> GLint -> GLint -> GLint -> IO ()
+
+foreign import CALLCONV unsafe "glRectiv" glRectiv ::
+   Ptr GLint -> Ptr GLint -> IO ()
+
+instance Rect GLint_ where
+   rect (Vertex2 x1 y1) (Vertex2 x2 y2) = liftIO $ glRecti x1 y1 x2 y2
+   rectv ptr1 ptr2 = liftIO $ glRectiv ptr1 ptr2
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glRectf" glRectf ::
+   GLfloat -> GLfloat -> GLfloat -> GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glRectfv" glRectfv ::
+   Ptr GLfloat -> Ptr GLfloat -> IO ()
+
+instance Rect GLfloat_ where
+   rect (Vertex2 x1 y1) (Vertex2 x2 y2) = liftIO $ glRectf x1 y1 x2 y2
+   rectv ptr1 ptr2 = liftIO $ glRectfv ptr1 ptr2
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glRectd" glRectd ::
+   GLdouble -> GLdouble -> GLdouble -> GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glRectdv" glRectdv ::
+   Ptr GLdouble -> Ptr GLdouble -> IO ()
+
+instance Rect GLdouble_ where
+   rect (Vertex2 x1 y1) (Vertex2 x2 y2) = liftIO $ glRectd x1 y1 x2 y2
+   rectv ptr1 ptr2 = liftIO $ glRectdv ptr1 ptr2
diff --git a/Graphics/Rendering/OGL/GL/RenderMode.hs b/Graphics/Rendering/OGL/GL/RenderMode.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/RenderMode.hs
@@ -0,0 +1,65 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.RenderMode
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module related to the current render mode.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.RenderMode (
+   RenderMode(..), withRenderMode, renderMode
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum, GLint )
+import Graphics.Rendering.OGL.GL.Exception ( finallyRet )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetRenderMode), getEnum1 )
+import Graphics.Rendering.OGL.GL.StateVar (
+   getIO, GettableStateVar, makeGettableStateVar )
+
+--------------------------------------------------------------------------------
+
+data RenderMode =
+     Render
+   | Feedback
+   | Select
+   deriving ( Eq, Ord, Show )
+
+marshalRenderMode :: RenderMode -> GLenum
+marshalRenderMode x = case x of
+   Render -> 0x1c00
+   Feedback -> 0x1c01
+   Select -> 0x1c02
+
+unmarshalRenderMode :: GLenum -> RenderMode
+unmarshalRenderMode x
+   | x == 0x1c00 = Render
+   | x == 0x1c01 = Feedback
+   | x == 0x1c02 = Select
+   | otherwise = error ("unmarshalRenderMode: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+withRenderMode :: RenderMode -> IO a -> IO (a, GLint)
+withRenderMode newMode action = do
+   oldMode <- getIO renderMode
+   setRenderMode newMode
+   action `finallyRet` setRenderMode oldMode
+
+setRenderMode :: RenderMode -> IO GLint
+setRenderMode = glRenderMode . marshalRenderMode
+
+foreign import CALLCONV unsafe "glRenderMode" glRenderMode :: GLenum -> IO GLint
+
+--------------------------------------------------------------------------------
+
+renderMode :: GettableStateVar RenderMode
+renderMode = makeGettableStateVar $ getEnum1 unmarshalRenderMode GetRenderMode
diff --git a/Graphics/Rendering/OGL/GL/SavingState.hs b/Graphics/Rendering/OGL/GL/SavingState.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/SavingState.hs
@@ -0,0 +1,118 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.SavingState
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 6.1.14 (Saving and Restoring State) of the
+-- OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.SavingState (
+   ServerAttributeGroup(..), preservingAttrib,
+   ClientAttributeGroup(..), preservingClientAttrib
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLbitfield )
+import Graphics.Rendering.OGL.GL.Exception ( bracket_ )
+
+--------------------------------------------------------------------------------
+
+data ServerAttributeGroup =
+     CurrentAttributes
+   | PointAttributes
+   | LineAttributes
+   | PolygonAttributes
+   | PolygonStippleAttributes
+   | PixelModeAttributes
+   | LightingAttributes
+   | FogAttributes
+   | DepthBufferAttributes
+   | AccumBufferAttributes
+   | StencilBufferAttributes
+   | ViewportAttributes
+   | TransformAttributes
+   | EnableAttributes
+   | ColorBufferAttributes
+   | HintAttributes
+   | EvalAttributes
+   | ListAttributes
+   | TextureAttributes
+   | ScissorAttributes
+   | MultisampleAttributes
+   | AllServerAttributes
+   deriving ( Eq, Ord, Show )
+
+marshalServerAttributeGroup :: ServerAttributeGroup -> GLbitfield
+marshalServerAttributeGroup x = case x of
+   CurrentAttributes -> 0x1
+   PointAttributes -> 0x2
+   LineAttributes -> 0x4
+   PolygonAttributes -> 0x8
+   PolygonStippleAttributes -> 0x10
+   PixelModeAttributes -> 0x20
+   LightingAttributes -> 0x40
+   FogAttributes -> 0x80
+   DepthBufferAttributes -> 0x100
+   AccumBufferAttributes -> 0x200
+   StencilBufferAttributes -> 0x400
+   ViewportAttributes -> 0x800
+   TransformAttributes -> 0x1000
+   EnableAttributes -> 0x2000
+   ColorBufferAttributes -> 0x4000
+   HintAttributes -> 0x8000
+   EvalAttributes -> 0x10000
+   ListAttributes -> 0x20000
+   TextureAttributes -> 0x40000
+   ScissorAttributes -> 0x80000
+   MultisampleAttributes -> 0x20000000
+   AllServerAttributes -> 0xffffffff
+
+--------------------------------------------------------------------------------
+
+preservingAttrib :: [ServerAttributeGroup] -> GL a -> GL a
+preservingAttrib groups f = liftIO $ bracket_ (pushAttrib groups) glPopAttrib (runGL f)
+
+pushAttrib :: [ServerAttributeGroup] -> IO ()
+pushAttrib = glPushAttrib . sum . map marshalServerAttributeGroup
+
+foreign import CALLCONV unsafe "glPushAttrib"
+   glPushAttrib :: GLbitfield -> IO ()
+
+foreign import CALLCONV unsafe "glPopAttrib"
+   glPopAttrib :: IO ()
+
+--------------------------------------------------------------------------------
+
+data ClientAttributeGroup =
+     PixelStoreAttributes
+   | VertexArrayAttributes
+   | AllClientAttributes
+   deriving ( Eq, Ord, Show )
+
+marshalClientAttributeGroup :: ClientAttributeGroup -> GLbitfield
+marshalClientAttributeGroup x = case x of
+   PixelStoreAttributes -> 0x1
+   VertexArrayAttributes -> 0x2
+   AllClientAttributes -> 0xffffffff
+
+--------------------------------------------------------------------------------
+
+preservingClientAttrib :: [ClientAttributeGroup] -> GL a -> GL a
+preservingClientAttrib groups x = liftIO $ 
+   bracket_ (pushClientAttrib groups) glPopClientAttrib (runGL x)
+
+pushClientAttrib :: [ClientAttributeGroup] -> IO ()
+pushClientAttrib = glPushClientAttrib . sum . map marshalClientAttributeGroup
+
+foreign import CALLCONV unsafe "glPushClientAttrib"
+   glPushClientAttrib :: GLbitfield -> IO ()
+
+foreign import CALLCONV unsafe "glPopClientAttrib"
+   glPopClientAttrib :: IO ()
diff --git a/Graphics/Rendering/OGL/GL/Selection.hs b/Graphics/Rendering/OGL/GL/Selection.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Selection.hs
@@ -0,0 +1,102 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Selection
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 5.2 (Selection) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Selection (
+   HitRecord(..), getHitRecords,
+   Name(..), withName, loadName, maxNameStackDepth, nameStackDepth,
+   RenderMode(..), renderMode
+) where
+
+import Foreign.Marshal.Array ( allocaArray )
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLint, GLsizei, GLuint, GLfloat )
+import Graphics.Rendering.OGL.GL.Exception ( bracket_ )
+import Graphics.Rendering.OGL.GL.IOState (
+   IOState, peekIOState, evalIOState, nTimes )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetMaxNameStackDepth,GetNameStackDepth), getSizei1 )
+import Graphics.Rendering.OGL.GL.RenderMode (
+   RenderMode(..), withRenderMode, renderMode )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar )
+
+--------------------------------------------------------------------------------
+
+data HitRecord = HitRecord GLfloat GLfloat [Name]
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+getHitRecords :: GLsizei -> GL a -> GL (a, Maybe [HitRecord])
+getHitRecords bufSize action = liftIO . 
+   allocaArray (fromIntegral bufSize) $ \buf -> do
+      glSelectBuffer bufSize buf
+      (value, numHits) <- withRenderMode Select $ do
+         glInitNames
+         runGL action
+      hits <- parseSelectionBuffer numHits buf
+      return (value, hits)
+
+foreign import CALLCONV unsafe "glInitNames" glInitNames :: IO ()
+
+foreign import CALLCONV unsafe "glSelectBuffer" glSelectBuffer ::
+   GLsizei -> Ptr GLuint -> IO ()
+
+--------------------------------------------------------------------------------
+
+parseSelectionBuffer :: GLint -> Ptr GLuint -> IO (Maybe [HitRecord])
+parseSelectionBuffer numHits buf
+   | numHits < 0 = return Nothing
+   | otherwise = fmap Just $ evalIOState (nTimes numHits parseSelectionHit) buf
+
+type Parser a = IOState GLuint a
+
+parseSelectionHit :: Parser HitRecord
+parseSelectionHit = do
+   numNames <- parseGLuint
+   minZ <- parseGLfloat
+   maxZ <- parseGLfloat
+   nameStack <- nTimes numNames parseName
+   return $ HitRecord minZ maxZ nameStack
+
+parseGLuint :: Parser GLuint
+parseGLuint = peekIOState
+
+parseGLfloat :: Parser GLfloat
+parseGLfloat = fmap (\x -> fromIntegral x / 0xffffffff) parseGLuint
+
+parseName :: Parser Name
+parseName = fmap Name parseGLuint
+
+--------------------------------------------------------------------------------
+
+newtype Name = Name GLuint
+   deriving ( Eq, Ord, Show )
+
+withName :: Name -> GL a -> GL a
+withName name f = liftIO $ bracket_ (glPushName name) glPopName (runGL f)
+
+foreign import CALLCONV unsafe "glPopName" glPopName :: IO ()
+
+foreign import CALLCONV unsafe "glPushName" glPushName :: Name -> IO ()
+
+foreign import CALLCONV unsafe "glLoadName" loadName :: Name -> GL ()
+
+maxNameStackDepth :: GettableStateVar GLsizei
+maxNameStackDepth = makeGettableStateVar (getSizei1 id GetMaxNameStackDepth)
+
+nameStackDepth :: GettableStateVar GLsizei
+nameStackDepth = makeGettableStateVar (getSizei1 id GetNameStackDepth)
diff --git a/Graphics/Rendering/OGL/GL/Shaders.hs b/Graphics/Rendering/OGL/GL/Shaders.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Shaders.hs
@@ -0,0 +1,717 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Shaders
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to sections 2.15 (Vertex Shaders) and section 3.11
+-- (Fragment Shaders) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Shaders (
+   -- * Shader Objects
+   Shader, VertexShader, FragmentShader, shaderDeleteStatus, shaderSource,
+   compileShader, compileStatus, shaderInfoLog,
+
+   -- * Program Objects
+   Program, programDeleteStatus, attachedShaders, linkProgram, linkStatus,
+   programInfoLog, validateProgram, validateStatus, currentProgram,
+
+   -- * Vertex attributes
+   attribLocation, VariableType(..), activeAttribs,
+
+   -- * Uniform variables
+   UniformLocation, uniformLocation, activeUniforms, Uniform(..),
+   UniformComponent,
+
+   -- * Implementation limits related to GLSL
+   maxVertexTextureImageUnits, maxTextureImageUnits,
+   maxCombinedTextureImageUnits, maxTextureCoords, maxVertexUniformComponents,
+   maxFragmentUniformComponents, maxVertexAttribs, maxVaryingFloats
+) where
+
+import Control.Monad ( replicateM, mapM_, foldM )
+import Control.Monad.Fix ( MonadFix(..) )
+import Data.Int
+import Data.List ( genericLength, (\\) )
+import Foreign.C.String ( peekCAStringLen, withCAStringLen )
+import Foreign.Marshal.Alloc ( alloca, allocaBytes )
+import Foreign.Marshal.Array ( allocaArray, withArray, peekArray )
+import Foreign.Marshal.Utils ( withMany )
+import Foreign.Ptr ( Ptr, castPtr, nullPtr )
+import Foreign.Storable ( Storable(peek,sizeOf) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLboolean, GLchar, GLint, GLuint, GLsizei, GLenum, GLfloat )
+import Graphics.Rendering.OGL.GL.BufferObjects ( ObjectName(..) )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.GLboolean ( unmarshalGLboolean )
+import Graphics.Rendering.OGL.GL.PeekPoke ( peek1 )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetMaxCombinedTextureImageUnits, GetMaxFragmentUniformComponents,
+            GetMaxTextureCoords, GetMaxTextureImageUnits,GetMaxVaryingFloats,
+            GetMaxVertexAttribs, GetMaxVertexTextureImageUnits,
+            GetMaxVertexUniformComponents, GetCurrentProgram),
+   getInteger1, getSizei1 )
+import Graphics.Rendering.OGL.GL.StateVar (
+   getIO, GettableStateVar, makeGettableStateVar, StateVar,
+   makeStateVar )
+import Graphics.Rendering.OGL.GL.VertexSpec (
+   AttribLocation(..), Vertex2(..), Vertex3(..), Vertex4(..), TexCoord1(..),
+   TexCoord2(..), TexCoord3(..), TexCoord4(..), Normal3(..), FogCoord1(..),
+   Color3(..), Color4(..), Index1(..) )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+#include "HsOpenGLTypes.h"
+
+--------------------------------------------------------------------------------
+
+type GLStringLen = (Ptr GLchar, GLsizei)
+
+peekGLstringLen :: GLStringLen -> IO String
+peekGLstringLen (p,l) = peekCAStringLen (castPtr p, fromIntegral l)
+
+withGLStringLen :: String -> (GLStringLen -> IO a) -> IO a
+withGLStringLen s act =
+   withCAStringLen s $ \(p,len) ->
+      act (castPtr p, fromIntegral len)
+
+--------------------------------------------------------------------------------
+
+newtype VertexShader = VertexShader { vertexShaderID :: GLuint }
+   deriving ( Eq, Ord, Show )
+
+newtype FragmentShader = FragmentShader { fragmentShaderID :: GLuint }
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+class (Eq s, Ord s, Show s, ObjectName s) => Shader s where
+   shaderID :: s -> GLuint
+   makeShader :: GLuint -> s
+   shaderType :: s -> GLenum
+
+instance Shader VertexShader where
+   makeShader = VertexShader
+   shaderID = vertexShaderID
+   shaderType = const 0x8B31
+
+instance Shader FragmentShader where
+   makeShader = FragmentShader
+   shaderID = fragmentShaderID
+   shaderType = const 0x8B30
+
+--------------------------------------------------------------------------------
+
+instance ObjectName VertexShader where
+   genObjectNames = liftIO . genShaderNames
+   deleteObjectNames = liftIO . deleteShaderNames
+   isObjectName = liftIO . isShaderName
+
+instance ObjectName FragmentShader where
+   genObjectNames = liftIO . genShaderNames
+   deleteObjectNames = liftIO . deleteShaderNames
+   isObjectName = liftIO . isShaderName
+
+genShaderNames :: Shader s => Int -> IO [s]
+genShaderNames n = replicateM n createShader
+
+createShader :: Shader s => IO s
+createShader = mfix (fmap makeShader . glCreateShader . shaderType)
+
+deleteShaderNames :: Shader s => [s] -> IO ()
+deleteShaderNames = mapM_ (glDeleteShader . shaderID)
+
+isShaderName :: Shader s => s -> IO Bool
+isShaderName = fmap unmarshalGLboolean . glIsShader . shaderID
+
+EXTENSION_ENTRY("OpenGL 2.0",glCreateShader,GLenum -> IO GLuint)
+EXTENSION_ENTRY("OpenGL 2.0",glDeleteShader,GLuint -> IO ())
+EXTENSION_ENTRY("OpenGL 2.0",glIsShader,GLuint -> IO GLboolean)
+
+--------------------------------------------------------------------------------
+
+compileShader :: Shader s => s -> GL ()
+compileShader = liftIO . glCompileShader . shaderID
+
+EXTENSION_ENTRY("OpenGL 2.0",glCompileShader,GLuint -> IO ())
+
+--------------------------------------------------------------------------------
+
+shaderSource :: Shader s => s -> StateVar [String]
+shaderSource shader =
+   makeStateVar (getShaderSource shader) (setShaderSource shader)
+
+setShaderSource :: Shader s => s -> [String] -> IO ()
+setShaderSource shader srcs = do
+   let len = genericLength srcs
+   withMany withGLStringLen srcs $ \charBufsAndLengths -> do
+      let (charBufs, lengths) = unzip charBufsAndLengths
+      withArray charBufs $ \charBufsBuf ->
+         withArray lengths $ \lengthsBuf ->
+            glShaderSource (shaderID shader) len charBufsBuf lengthsBuf
+
+EXTENSION_ENTRY("OpenGL 2.0",glShaderSource,GLuint -> GLsizei -> Ptr (Ptr GLchar) -> Ptr GLint -> IO ())
+
+getShaderSource :: Shader s => s -> IO [String]
+getShaderSource shader = do
+   src <- getIO (stringQuery (shaderSourceLength shader)
+                           (glGetShaderSource (shaderID shader)))
+   return [src]
+
+EXTENSION_ENTRY("OpenGL 2.0",glGetShaderSource,GLuint -> GLsizei -> Ptr GLsizei -> Ptr GLchar -> IO ())
+
+stringQuery :: GettableStateVar GLsizei -> (GLsizei -> Ptr GLsizei -> Ptr GLchar -> IO ()) -> GettableStateVar String
+stringQuery lengthVar getStr =
+   makeGettableStateVar $ do
+      len <- getIO lengthVar -- Note: This includes the NUL character!
+      if len == 0
+        then return ""
+        else allocaArray (fromIntegral len) $ \buf -> do
+                getStr len nullPtr buf
+                peekGLstringLen (buf, len-1)
+
+--------------------------------------------------------------------------------
+
+shaderInfoLog :: Shader s => s -> GettableStateVar String
+shaderInfoLog shader =
+   stringQuery (shaderInfoLogLength shader) (glGetShaderInfoLog (shaderID shader))
+
+EXTENSION_ENTRY("OpenGL 2.0",glGetShaderInfoLog,GLuint -> GLsizei -> Ptr GLsizei -> Ptr GLchar -> IO ())
+
+--------------------------------------------------------------------------------
+
+shaderDeleteStatus :: Shader s => s -> GettableStateVar Bool
+shaderDeleteStatus = shaderVar unmarshalGLboolean ShaderDeleteStatus
+
+compileStatus :: Shader s => s -> GettableStateVar Bool
+compileStatus = shaderVar unmarshalGLboolean CompileStatus
+
+shaderInfoLogLength :: Shader s => s -> GettableStateVar GLsizei
+shaderInfoLogLength = shaderVar fromIntegral ShaderInfoLogLength
+
+shaderSourceLength :: Shader s => s -> GettableStateVar GLsizei
+shaderSourceLength = shaderVar fromIntegral ShaderSourceLength
+
+shaderTypeEnum :: Shader s => s -> GettableStateVar GLenum
+shaderTypeEnum = shaderVar fromIntegral ShaderType
+
+--------------------------------------------------------------------------------
+
+data GetShaderPName =
+     ShaderDeleteStatus
+   | CompileStatus
+   | ShaderInfoLogLength
+   | ShaderSourceLength
+   | ShaderType
+
+marshalGetShaderPName :: GetShaderPName -> GLenum
+marshalGetShaderPName x = case x of
+   ShaderDeleteStatus -> 0x8B80
+   CompileStatus -> 0x8B81
+   ShaderInfoLogLength -> 0x8B84
+   ShaderSourceLength -> 0x8B88
+   ShaderType -> 0x8B4F
+
+shaderVar :: Shader s => (GLint -> a) -> GetShaderPName -> s -> GettableStateVar a
+shaderVar f p shader =
+   makeGettableStateVar $
+      alloca $ \buf -> do
+         glGetShaderiv (shaderID shader) (marshalGetShaderPName p) buf
+         peek1 f buf
+
+EXTENSION_ENTRY("OpenGL 2.0",glGetShaderiv,GLuint -> GLenum -> Ptr GLint -> IO ())
+
+--------------------------------------------------------------------------------
+
+newtype Program = Program { programID :: GLuint }
+   deriving ( Eq, Ord, Show )
+
+instance ObjectName Program where
+   genObjectNames n = liftIO . replicateM n $ fmap Program glCreateProgram
+   deleteObjectNames = liftIO . mapM_ (glDeleteProgram . programID)
+   isObjectName = liftIO . fmap unmarshalGLboolean . glIsProgram . programID
+
+EXTENSION_ENTRY("OpenGL 2.0",glCreateProgram,IO GLuint)
+EXTENSION_ENTRY("OpenGL 2.0",glDeleteProgram,GLuint -> IO ())
+EXTENSION_ENTRY("OpenGL 2.0",glIsProgram,GLuint -> IO GLboolean)
+
+--------------------------------------------------------------------------------
+
+attachedShaders :: Program -> StateVar ([VertexShader],[FragmentShader])
+attachedShaders program =
+   makeStateVar (getAttachedShaders program) (setAttachedShaders program)
+
+getAttachedShaders :: Program -> IO ([VertexShader],[FragmentShader])
+getAttachedShaders program = getAttachedShaderIDs program >>= splitShaderIDs
+
+getAttachedShaderIDs :: Program -> IO [GLuint]
+getAttachedShaderIDs program = do
+   numShaders <- getIO (numAttachedShaders program)
+   allocaArray (fromIntegral numShaders) $ \buf -> do
+      glGetAttachedShaders (programID program) numShaders nullPtr buf
+      peekArray (fromIntegral numShaders) buf
+
+EXTENSION_ENTRY("OpenGL 2.0",glGetAttachedShaders,GLuint -> GLsizei -> Ptr GLsizei -> Ptr GLuint -> IO ())
+
+splitShaderIDs :: [GLuint] -> IO ([VertexShader],[FragmentShader])
+splitShaderIDs ids = do
+   (vs, fs) <- partitionM isVertexShaderID ids
+   return (map VertexShader vs, map FragmentShader fs)
+
+isVertexShaderID :: GLuint -> IO Bool
+isVertexShaderID x = do
+   t <- getIO (shaderTypeEnum (VertexShader x))
+   return $ t == shaderType (undefined :: VertexShader)
+
+partitionM :: (a -> IO Bool) -> [a] -> IO ([a],[a])
+partitionM p = foldM select ([],[])
+   where select (ts, fs) x = do
+            b <- p x
+            return $ if b then (x:ts, fs) else (ts, x:fs)
+
+setAttachedShaders :: Program -> ([VertexShader],[FragmentShader]) -> IO ()
+setAttachedShaders program (vs, fs) = do
+   currentIDs <- getAttachedShaderIDs program
+   let newIDs = map shaderID vs ++ map shaderID fs
+   mapM_ (glAttachShader program) (newIDs \\ currentIDs)
+   mapM_ (glDetachShader program) (currentIDs \\ newIDs)
+
+EXTENSION_ENTRY("OpenGL 2.0",glAttachShader,Program -> GLuint -> IO ())
+EXTENSION_ENTRY("OpenGL 2.0",glDetachShader,Program -> GLuint -> IO ())
+
+--------------------------------------------------------------------------------
+
+linkProgram :: Program -> GL ()
+linkProgram = liftIO . glLinkProgram
+
+EXTENSION_ENTRY("OpenGL 2.0",glLinkProgram,Program -> IO ())
+
+currentProgram :: StateVar (Maybe Program)
+currentProgram =
+   makeStateVar
+      (do p <- getCurrentProgram
+          return $ if p == noProgram then Nothing else Just p)
+      (glUseProgram . maybe noProgram id)
+
+getCurrentProgram :: IO Program
+getCurrentProgram = fmap Program $ getInteger1 fromIntegral GetCurrentProgram
+
+noProgram :: Program
+noProgram = Program 0
+
+EXTENSION_ENTRY("OpenGL 2.0",glUseProgram,Program -> IO ())
+
+validateProgram :: Program -> GL ()
+validateProgram = liftIO . glValidateProgram
+
+EXTENSION_ENTRY("OpenGL 2.0",glValidateProgram,Program -> IO ())
+
+programInfoLog :: Program -> GettableStateVar String
+programInfoLog p =
+   stringQuery (programInfoLogLength p) (glGetProgramInfoLog (programID p))
+
+EXTENSION_ENTRY("OpenGL 2.0",glGetProgramInfoLog,GLuint -> GLsizei -> Ptr GLsizei -> Ptr GLchar -> IO ())
+
+--------------------------------------------------------------------------------
+
+programDeleteStatus :: Program -> GettableStateVar Bool
+programDeleteStatus = programVar unmarshalGLboolean ProgramDeleteStatus
+
+linkStatus :: Program -> GettableStateVar Bool
+linkStatus = programVar unmarshalGLboolean LinkStatus
+
+validateStatus :: Program -> GettableStateVar Bool
+validateStatus = programVar unmarshalGLboolean ValidateStatus
+
+programInfoLogLength :: Program -> GettableStateVar GLsizei
+programInfoLogLength = programVar fromIntegral ProgramInfoLogLength
+
+numAttachedShaders :: Program -> GettableStateVar GLsizei
+numAttachedShaders = programVar fromIntegral AttachedShaders
+
+activeAttributes :: Program -> GettableStateVar GLuint
+activeAttributes = programVar fromIntegral ActiveAttributes
+
+activeAttributeMaxLength :: Program -> GettableStateVar GLsizei
+activeAttributeMaxLength = programVar fromIntegral ActiveAttributeMaxLength
+
+numActiveUniforms :: Program -> GettableStateVar GLuint
+numActiveUniforms = programVar fromIntegral ActiveUniforms
+
+activeUniformMaxLength :: Program -> GettableStateVar GLsizei
+activeUniformMaxLength = programVar fromIntegral ActiveUniformMaxLength
+
+--------------------------------------------------------------------------------
+
+data GetProgramPName =
+     ProgramDeleteStatus
+   | LinkStatus
+   | ValidateStatus
+   | ProgramInfoLogLength
+   | AttachedShaders
+   | ActiveAttributes
+   | ActiveAttributeMaxLength
+   | ActiveUniforms
+   | ActiveUniformMaxLength
+
+marshalGetProgramPName :: GetProgramPName -> GLenum
+marshalGetProgramPName x = case x of
+   ProgramDeleteStatus -> 0x8B80
+   LinkStatus -> 0x8B82
+   ValidateStatus -> 0x8B83
+   ProgramInfoLogLength -> 0x8B84
+   AttachedShaders -> 0x8B85
+   ActiveAttributes -> 0x8B89
+   ActiveAttributeMaxLength -> 0x8B8A
+   ActiveUniforms -> 0x8B86
+   ActiveUniformMaxLength -> 0x8B87
+
+programVar :: (GLint -> a) -> GetProgramPName -> Program -> GettableStateVar a
+programVar f p program =
+   makeGettableStateVar $
+      alloca $ \buf -> do
+         glGetProgramiv (programID program) (marshalGetProgramPName p) buf
+         peek1 f buf
+
+EXTENSION_ENTRY("OpenGL 2.0",glGetProgramiv,GLuint -> GLenum -> Ptr GLint -> IO ())
+
+--------------------------------------------------------------------------------
+
+attribLocation :: Program -> String -> StateVar AttribLocation
+attribLocation program name =
+   makeStateVar (getAttribLocation program name)
+                (\location -> bindAttribLocation program location name)
+
+getAttribLocation :: Program -> String -> IO AttribLocation
+getAttribLocation program name =
+   withGLStringLen name $ \(buf,_) ->
+      fmap (AttribLocation . fromIntegral) $
+        glGetAttribLocation program buf
+
+EXTENSION_ENTRY("OpenGL 2.0",glGetAttribLocation,Program -> Ptr GLchar -> IO GLint)
+
+bindAttribLocation :: Program -> AttribLocation -> String -> IO ()
+bindAttribLocation program location name =
+   withGLStringLen name $ \(buf,_) ->
+      glBindAttribLocation program location buf
+
+EXTENSION_ENTRY("OpenGL 2.0",glBindAttribLocation,Program -> AttribLocation -> Ptr GLchar -> IO ())
+
+--------------------------------------------------------------------------------
+
+data VariableType =
+     Float'
+   | FloatVec2
+   | FloatVec3
+   | FloatVec4
+   | FloatMat2
+   | FloatMat3
+   | FloatMat4
+   | Int'
+   | IntVec2
+   | IntVec3
+   | IntVec4
+   | Bool
+   | BoolVec2
+   | BoolVec3
+   | BoolVec4
+   | Sampler1D
+   | Sampler2D
+   | Sampler3D
+   | SamplerCube
+   | Sampler1DShadow
+   | Sampler2DShadow
+   deriving ( Eq, Ord, Show )
+
+unmarshalVariableType :: GLenum -> VariableType
+unmarshalVariableType x
+   | x == 0x1406 = Float'
+   | x == 0x8B50 = FloatVec2
+   | x == 0x8B51 = FloatVec3
+   | x == 0x8B52 = FloatVec4
+   | x == 0x8B5A = FloatMat2
+   | x == 0x8B5B = FloatMat3
+   | x == 0x8B5C = FloatMat4
+   | x == 0x1404 = Int'
+   | x == 0x8B53 = IntVec2
+   | x == 0x8B54 = IntVec3
+   | x == 0x8B55 = IntVec4
+   | x == 0x8B56 = Bool
+   | x == 0x8B57 = BoolVec2
+   | x == 0x8B58 = BoolVec3
+   | x == 0x8B59 = BoolVec4
+   | x == 0x8B5D = Sampler1D
+   | x == 0x8B5E = Sampler2D
+   | x == 0x8B5F = Sampler3D
+   | x == 0x8B60 = SamplerCube
+   | x == 0x8B61 = Sampler1DShadow
+   | x == 0x8B62 = Sampler2DShadow
+   | otherwise = error ("unmarshalVariableType: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+activeVars :: (Program -> GettableStateVar GLuint)
+           -> (Program -> GettableStateVar GLsizei)
+           -> (Program -> GLuint -> GLsizei -> Ptr GLsizei -> Ptr GLint -> Ptr GLenum -> Ptr GLchar -> IO ())
+           -> Program -> GettableStateVar [(GLint,VariableType,String)]
+activeVars numVars maxLength getter program =
+   makeGettableStateVar $ do
+      numActiveVars <- getIO (numVars program)
+      maxLen <- getIO (maxLength program)
+      allocaArray (fromIntegral maxLen) $ \nameBuf ->
+         alloca $ \nameLengthBuf ->
+            alloca $ \sizeBuf ->
+               alloca $ \typeBuf ->
+                  flip mapM [0 .. numActiveVars - 1] $ \i -> do
+                    getter program i maxLen nameLengthBuf sizeBuf typeBuf nameBuf
+                    l <- peek nameLengthBuf
+                    s <- peek sizeBuf
+                    t <- peek typeBuf
+                    n <- peekGLstringLen (nameBuf, l)
+                    return (s, unmarshalVariableType t, n)
+
+activeAttribs :: Program -> GettableStateVar [(GLint,VariableType,String)]
+activeAttribs = activeVars activeAttributes activeAttributeMaxLength glGetActiveAttrib
+
+EXTENSION_ENTRY("OpenGL 2.0",glGetActiveAttrib,Program -> GLuint -> GLsizei -> Ptr GLsizei -> Ptr GLint -> Ptr GLenum -> Ptr GLchar -> IO ())
+
+--------------------------------------------------------------------------------
+
+newtype UniformLocation = UniformLocation GLint
+   deriving ( Eq, Ord, Show )
+
+uniformLocation :: Program -> String -> GettableStateVar UniformLocation
+uniformLocation program name =
+   makeGettableStateVar $
+      withGLStringLen name $ \(buf,_) ->
+         fmap UniformLocation $
+            glGetUniformLocation program buf
+
+EXTENSION_ENTRY("OpenGL 2.0",glGetUniformLocation,Program -> Ptr GLchar -> IO GLint)
+
+--------------------------------------------------------------------------------
+
+activeUniforms :: Program -> GettableStateVar [(GLint,VariableType,String)]
+activeUniforms = activeVars numActiveUniforms activeUniformMaxLength glGetActiveUniform
+
+EXTENSION_ENTRY("OpenGL 2.0",glGetActiveUniform,Program -> GLuint -> GLsizei -> Ptr GLsizei -> Ptr GLint -> Ptr GLenum -> Ptr GLchar -> IO ())
+
+--------------------------------------------------------------------------------
+
+class Storable a => UniformComponent a where
+   uniform1 :: UniformLocation -> a -> GL ()
+   uniform2 :: UniformLocation -> a -> a -> GL ()
+   uniform3 :: UniformLocation -> a -> a -> a -> GL ()
+   uniform4 :: UniformLocation -> a -> a -> a -> a -> GL ()
+
+   getUniform :: Storable (b a) => Program -> UniformLocation -> Ptr (b a) -> GL ()
+
+   uniform1v :: UniformLocation -> GLsizei -> Ptr a -> GL ()
+   uniform2v :: UniformLocation -> GLsizei -> Ptr a -> GL ()
+   uniform3v :: UniformLocation -> GLsizei -> Ptr a -> GL ()
+   uniform4v :: UniformLocation -> GLsizei -> Ptr a -> GL ()
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("OpenGL 2.0",glUniform1i,UniformLocation -> GLint -> GL ())
+EXTENSION_ENTRY("OpenGL 2.0",glUniform2i,UniformLocation -> GLint -> GLint -> GL ())
+EXTENSION_ENTRY("OpenGL 2.0",glUniform3i,UniformLocation -> GLint -> GLint -> GLint -> GL ())
+EXTENSION_ENTRY("OpenGL 2.0",glUniform4i,UniformLocation -> GLint -> GLint -> GLint -> GLint -> GL ())
+
+EXTENSION_ENTRY("OpenGL 2.0",glGetUniformiv,Program -> UniformLocation -> Ptr GLint -> GL ())
+
+EXTENSION_ENTRY("OpenGL 2.0",glUniform1iv,UniformLocation -> GLsizei -> Ptr GLint -> GL ())
+EXTENSION_ENTRY("OpenGL 2.0",glUniform2iv,UniformLocation -> GLsizei -> Ptr GLint -> GL ())
+EXTENSION_ENTRY("OpenGL 2.0",glUniform3iv,UniformLocation -> GLsizei -> Ptr GLint -> GL ())
+EXTENSION_ENTRY("OpenGL 2.0",glUniform4iv,UniformLocation -> GLsizei -> Ptr GLint -> GL ())
+
+instance UniformComponent GLint_ where
+   uniform1 = glUniform1i
+   uniform2 = glUniform2i
+   uniform3 = glUniform3i
+   uniform4 = glUniform4i
+
+   getUniform program location = glGetUniformiv program location . castPtr
+
+   uniform1v = glUniform1iv
+   uniform2v = glUniform2iv
+   uniform3v = glUniform3iv
+   uniform4v = glUniform4iv
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("OpenGL 2.0",glUniform1f,UniformLocation -> GLfloat -> GL ())
+EXTENSION_ENTRY("OpenGL 2.0",glUniform2f,UniformLocation -> GLfloat -> GLfloat -> GL ())
+EXTENSION_ENTRY("OpenGL 2.0",glUniform3f,UniformLocation -> GLfloat -> GLfloat -> GLfloat -> GL ())
+EXTENSION_ENTRY("OpenGL 2.0",glUniform4f,UniformLocation -> GLfloat -> GLfloat -> GLfloat -> GLfloat -> GL ())
+
+EXTENSION_ENTRY("OpenGL 2.0",glGetUniformfv,Program -> UniformLocation -> Ptr GLfloat -> GL ())
+
+EXTENSION_ENTRY("OpenGL 2.0",glUniform1fv,UniformLocation -> GLsizei -> Ptr GLfloat -> GL ())
+EXTENSION_ENTRY("OpenGL 2.0",glUniform2fv,UniformLocation -> GLsizei -> Ptr GLfloat -> GL ())
+EXTENSION_ENTRY("OpenGL 2.0",glUniform3fv,UniformLocation -> GLsizei -> Ptr GLfloat -> GL ())
+EXTENSION_ENTRY("OpenGL 2.0",glUniform4fv,UniformLocation -> GLsizei -> Ptr GLfloat -> GL ())
+
+instance UniformComponent GLfloat_ where
+   uniform1 = glUniform1f
+   uniform2 = glUniform2f
+   uniform3 = glUniform3f
+   uniform4 = glUniform4f
+
+   getUniform program location = glGetUniformfv program location . castPtr
+
+   uniform1v = glUniform1fv
+   uniform2v = glUniform2fv
+   uniform3v = glUniform3fv
+   uniform4v = glUniform4fv
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("OpenGL 2.0",glUniformMatrix2fv,UniformLocation -> GLsizei -> GLboolean -> Ptr GLfloat -> GL ())
+EXTENSION_ENTRY("OpenGL 2.0",glUniformMatrix3fv,UniformLocation -> GLsizei -> GLboolean -> Ptr GLfloat -> GL ())
+EXTENSION_ENTRY("OpenGL 2.0",glUniformMatrix4fv,UniformLocation -> GLsizei -> GLboolean -> Ptr GLfloat -> GL ())
+EXTENSION_ENTRY("OpenGL 2.1",glUniformMatrix2x3fv,UniformLocation -> GLsizei -> GLboolean -> Ptr GLfloat -> GL ())
+EXTENSION_ENTRY("OpenGL 2.1",glUniformMatrix3x2fv,UniformLocation -> GLsizei -> GLboolean -> Ptr GLfloat -> GL ())
+EXTENSION_ENTRY("OpenGL 2.1",glUniformMatrix2x4fv,UniformLocation -> GLsizei -> GLboolean -> Ptr GLfloat -> GL ())
+EXTENSION_ENTRY("OpenGL 2.1",glUniformMatrix4x2fv,UniformLocation -> GLsizei -> GLboolean -> Ptr GLfloat -> GL ())
+EXTENSION_ENTRY("OpenGL 2.1",glUniformMatrix3x4fv,UniformLocation -> GLsizei -> GLboolean -> Ptr GLfloat -> GL ())
+EXTENSION_ENTRY("OpenGL 2.1",glUniformMatrix4x3fv,UniformLocation -> GLsizei -> GLboolean -> Ptr GLfloat -> GL ())
+
+--------------------------------------------------------------------------------
+
+class Uniform a where
+   uniform :: UniformLocation -> StateVar a
+   uniformv :: UniformLocation -> GLsizei -> Ptr a -> GL ()
+
+maxComponentSize :: Int
+maxComponentSize = sizeOf (undefined :: GLint) `max` sizeOf (undefined :: GLfloat)
+
+maxNumComponents :: Int
+maxNumComponents = 16
+
+maxUniformBufferSize :: Int
+maxUniformBufferSize = maxComponentSize * maxNumComponents
+
+makeUniformVar :: (UniformComponent a, Storable (b a))
+               => (UniformLocation -> b a -> GL ())
+               -> UniformLocation -> StateVar (b a)
+makeUniformVar setter location = makeStateVar getter (runGL . setter location)
+   where getter = do
+            program <- getCurrentProgram
+            allocaBytes maxUniformBufferSize  $ \buf -> do
+            runGL $ getUniform program location buf
+            peek buf
+
+instance UniformComponent a => Uniform (Vertex2 a) where
+   uniform = makeUniformVar $ \location (Vertex2 x y) -> uniform2 location x y
+   uniformv location count = uniform2v location count . (castPtr :: Ptr (Vertex2 b) -> Ptr b)
+
+instance UniformComponent a => Uniform (Vertex3 a) where
+   uniform = makeUniformVar $ \location (Vertex3 x y z) -> uniform3 location x y z
+   uniformv location count = uniform3v location count . (castPtr :: Ptr (Vertex3 b) -> Ptr b)
+
+instance UniformComponent a => Uniform (Vertex4 a) where
+   uniform = makeUniformVar $ \location (Vertex4 x y z w) -> uniform4 location x y z w
+   uniformv location count = uniform4v location count . (castPtr :: Ptr (Vertex4 b) -> Ptr b)
+
+instance UniformComponent a => Uniform (TexCoord1 a) where
+   uniform = makeUniformVar $ \location (TexCoord1 s) -> uniform1 location s
+   uniformv location count = uniform1v location count . (castPtr :: Ptr (TexCoord1 b) -> Ptr b)
+
+instance UniformComponent a => Uniform (TexCoord2 a) where
+   uniform = makeUniformVar $ \location (TexCoord2 s t) -> uniform2 location s t
+   uniformv location count = uniform2v location count . (castPtr :: Ptr (TexCoord2 b) -> Ptr b)
+
+instance UniformComponent a => Uniform (TexCoord3 a) where
+   uniform = makeUniformVar $ \location (TexCoord3 s t r) -> uniform3 location s t  r
+   uniformv location count = uniform3v location count . (castPtr :: Ptr (TexCoord3 b) -> Ptr b)
+
+instance UniformComponent a => Uniform (TexCoord4 a) where
+   uniform = makeUniformVar $ \location (TexCoord4 s t r q) -> uniform4 location s t  r q
+   uniformv location count = uniform4v location count . (castPtr :: Ptr (TexCoord4 b) -> Ptr b)
+
+instance UniformComponent a => Uniform (Normal3 a) where
+   uniform = makeUniformVar $ \location (Normal3 x y z) -> uniform3 location x y z
+   uniformv location count = uniform3v location count . (castPtr :: Ptr (Normal3 b) -> Ptr b)
+
+instance UniformComponent a => Uniform (FogCoord1 a) where
+   uniform = makeUniformVar $ \location (FogCoord1 c) -> uniform1 location c
+   uniformv location count = uniform1v location count . (castPtr :: Ptr (FogCoord1 b) -> Ptr b)
+
+instance UniformComponent a => Uniform (Color3 a) where
+   uniform = makeUniformVar $ \location (Color3 r g b) -> uniform3 location r g b
+   uniformv location count = uniform3v location count . (castPtr :: Ptr (Color3 b) -> Ptr b)
+
+instance UniformComponent a => Uniform (Color4 a) where
+   uniform = makeUniformVar $ \location (Color4 r g b a) -> uniform4 location r g b a
+   uniformv location count = uniform4v location count . (castPtr :: Ptr (Color4 b) -> Ptr b)
+
+instance UniformComponent a => Uniform (Index1 a) where
+   uniform = makeUniformVar $ \location (Index1 i) -> uniform1 location i
+   uniformv location count = uniform1v location count . (castPtr :: Ptr (Index1 b) -> Ptr b)
+
+--------------------------------------------------------------------------------
+
+-- | Contains the number of hardware units that can be used to access texture
+-- maps from the vertex processor. The minimum legal value is 0.
+
+maxVertexTextureImageUnits :: GettableStateVar GLsizei
+maxVertexTextureImageUnits = getLimit GetMaxVertexTextureImageUnits
+
+-- | Contains the total number of hardware units that can be used to access
+-- texture maps from the fragment processor. The minimum legal value is 2.
+
+maxTextureImageUnits :: GettableStateVar GLsizei
+maxTextureImageUnits = getLimit GetMaxTextureImageUnits
+
+-- | Contains the total number of hardware units that can be used to access
+-- texture maps from the vertex processor and the fragment processor combined.
+-- Note: If the vertex shader and the fragment processing stage access the same
+-- texture image unit, then that counts as using two texture image units. The
+-- minimum legal value is 2.
+
+maxCombinedTextureImageUnits :: GettableStateVar GLsizei
+maxCombinedTextureImageUnits = getLimit GetMaxCombinedTextureImageUnits
+
+-- | Contains the number of texture coordinate sets that are available. The
+-- minimum legal value is 2.
+
+maxTextureCoords :: GettableStateVar GLsizei
+maxTextureCoords = getLimit GetMaxTextureCoords
+
+-- | Contains the number of individual components (i.e., floating-point, integer
+-- or boolean values) that are available for vertex shader uniform variables.
+-- The minimum legal value is 512.
+maxVertexUniformComponents :: GettableStateVar GLsizei
+maxVertexUniformComponents = getLimit GetMaxVertexUniformComponents
+
+-- | Contains the number of individual components (i.e., floating-point, integer
+-- or boolean values) that are available for fragment shader uniform variables.
+-- The minimum legal value is 64.
+
+maxFragmentUniformComponents :: GettableStateVar GLsizei
+maxFragmentUniformComponents = getLimit GetMaxFragmentUniformComponents
+
+-- | Contains the number of active vertex attributes that are available. The
+-- minimum legal value is 16.
+
+maxVertexAttribs :: GettableStateVar GLsizei
+maxVertexAttribs = getLimit GetMaxVertexAttribs
+
+-- | Contains the number of individual floating-point values available for
+-- varying variables. The minimum legal value is 32.
+
+maxVaryingFloats :: GettableStateVar GLsizei
+maxVaryingFloats = getLimit GetMaxVaryingFloats
+
+getLimit :: GetPName -> GettableStateVar GLsizei
+getLimit = makeGettableStateVar . getSizei1 id
diff --git a/Graphics/Rendering/OGL/GL/StateVar.hs b/Graphics/Rendering/OGL/GL/StateVar.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/StateVar.hs
@@ -0,0 +1,110 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.StateVar
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.StateVar (   
+   HasGetter(..),
+   GettableStateVar, makeGettableStateVar,
+   HasSetter(..), set,
+   SettableStateVar, makeSettableStateVar,
+   StateVar, makeStateVar,
+   ($~), ($=!), ($~!), getIO, ($$=)
+) where
+
+import Data.IORef ( IORef, readIORef, writeIORef )
+
+import Graphics.Rendering.OGL.Monad
+--------------------------------------------------------------------------------
+-- | compatibility: '$=' in the IO monad.
+($$=) :: HasSetter g => g a -> a -> IO ()
+($$=) x y = runGL (x $= y)
+
+-- | compatibility: 'get' in the IO monad.
+getIO :: HasGetter g => g a -> IO a
+getIO = runGL . get
+
+--------------------------------------------------------------------------------
+infixr 2 $=
+
+--------------------------------------------------------------------------------
+
+class HasGetter g where
+   get :: MonadGL m => g a -> m a
+
+--------------------------------------------------------------------------------
+
+newtype GettableStateVar a = GettableStateVar (IO a)
+
+instance HasGetter GettableStateVar where
+   get (GettableStateVar g) = liftIO g
+
+makeGettableStateVar :: IO a -> GettableStateVar a
+makeGettableStateVar = GettableStateVar
+
+--------------------------------------------------------------------------------
+
+class HasSetter s where
+   ($=) :: MonadGL m => s a -> a -> m ()
+
+{-# DEPRECATED set "use `sequence_' instead" #-}
+set :: MonadGL m => [IO ()] -> m ()
+set = liftIO . sequence_
+
+--------------------------------------------------------------------------------
+
+newtype SettableStateVar a = SettableStateVar (a -> IO ())
+
+instance HasSetter SettableStateVar where
+   ($=) (SettableStateVar s) a = liftIO $ s a
+
+-- | A strict variant of '$='.
+($=!) :: (HasSetter s, MonadGL m) => s a -> a -> m ()
+v $=! x = x `seq` v $= x
+
+makeSettableStateVar :: (a -> IO ()) -> SettableStateVar a
+makeSettableStateVar = SettableStateVar
+
+--------------------------------------------------------------------------------
+
+data StateVar a =
+   StateVar (GettableStateVar a) (SettableStateVar a)
+
+instance HasGetter StateVar where
+   get (StateVar g _) = get g
+
+instance HasSetter StateVar where
+   ($=) (StateVar _ s) a = s $= a
+
+makeStateVar :: IO a -> (a -> IO ()) -> StateVar a
+makeStateVar g s = StateVar (makeGettableStateVar g) (makeSettableStateVar s)
+
+--------------------------------------------------------------------------------
+
+-- | A modificator convenience function.
+
+($~) :: (HasGetter v, HasSetter v, MonadGL m) => v a -> (a -> a) -> m ()
+v $~ f = do
+   x <- get v
+   v $= f x
+
+-- | A strict variant of '$~'.
+($~!) :: (HasGetter v, HasSetter v, MonadGL m) => v a -> (a -> a) -> m ()
+v $~! f = do
+   x <- get v
+   v $=! f x
+
+--------------------------------------------------------------------------------
+
+instance HasGetter IORef where
+   get = liftIO . readIORef
+
+instance HasSetter IORef where
+   ($=) a b = liftIO $ writeIORef a b
diff --git a/Graphics/Rendering/OGL/GL/StringQueries.hs b/Graphics/Rendering/OGL/GL/StringQueries.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/StringQueries.hs
@@ -0,0 +1,91 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.StringQueries
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to parts of section 6.1.11 (Pointer and String
+-- Queries) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.StringQueries (
+   vendor, renderer, glVersion, glExtensions, shadingLanguageVersion, majorMinor
+) where
+
+import Data.Char ( isDigit )
+import Foreign.C.String ( peekCString )
+import Foreign.Ptr ( Ptr, nullPtr, castPtr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum, GLubyte )
+import Graphics.Rendering.OGL.GL.StateVar (
+   HasGetter(get), GettableStateVar, makeGettableStateVar )
+
+--------------------------------------------------------------------------------
+
+vendor :: GettableStateVar String
+vendor = makeGettableStateVar (getString Vendor)
+
+renderer :: GettableStateVar String
+renderer = makeGettableStateVar (getString Renderer)
+
+glVersion :: GettableStateVar String
+glVersion = makeGettableStateVar (getString Version)
+
+glExtensions :: GettableStateVar [String]
+glExtensions = makeGettableStateVar (fmap words $ getString Extensions)
+
+shadingLanguageVersion :: GettableStateVar String
+shadingLanguageVersion = makeGettableStateVar (getString ShadingLanguageVersion)
+
+--------------------------------------------------------------------------------
+
+data StringName =
+     Vendor
+   | Renderer
+   | Version
+   | Extensions
+   | ShadingLanguageVersion
+
+marshalStringName :: StringName -> GLenum
+marshalStringName x = case x of
+   Vendor -> 0x1f00
+   Renderer -> 0x1f01
+   Version -> 0x1f02
+   Extensions -> 0x1f03
+   ShadingLanguageVersion -> 0x8b8c
+
+--------------------------------------------------------------------------------
+
+getString :: StringName -> IO String
+getString n = do
+   ptr <- glGetString (marshalStringName n)
+   if ptr == nullPtr
+      then return ""
+      else peekCString (castPtr ptr)
+
+foreign import CALLCONV unsafe "glGetString" glGetString ::
+   GLenum -> IO (Ptr GLubyte)
+
+--------------------------------------------------------------------------------
+
+-- | A utility function to be used with e.g. 'glVersion' or
+-- 'shadingLanguageVersion', transforming a variable containing a string of the
+-- form /major.minor[optional rest]/ into a variable containing a numeric
+-- major\/minor version. If the string is malformed, which should never happen
+-- with a sane OpenGL implementation, it is transformed to @(-1,-1)@.
+
+majorMinor :: GettableStateVar String -> GettableStateVar (Int, Int)
+majorMinor = makeGettableStateVar . fmap parse . runGL . get
+   where defaultVersion = (-1, -1)
+         parse str =
+            case span isDigit str of
+               (major@(_:_), '.':rest) ->
+                  case span isDigit rest of
+                     (minor@(_:_), _) -> (read major, read minor)
+                     _ -> defaultVersion
+               _ -> defaultVersion
diff --git a/Graphics/Rendering/OGL/GL/Texturing.hs b/Graphics/Rendering/OGL/GL/Texturing.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Texturing.hs
@@ -0,0 +1,29 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Texturing
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.8 (Texturing) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Texturing (
+   module Graphics.Rendering.OGL.GL.Texturing.Specification,
+   module Graphics.Rendering.OGL.GL.Texturing.Parameters,
+   module Graphics.Rendering.OGL.GL.Texturing.Objects,
+   module Graphics.Rendering.OGL.GL.Texturing.Environments,
+   module Graphics.Rendering.OGL.GL.Texturing.Application,
+   module Graphics.Rendering.OGL.GL.Texturing.Queries
+) where
+
+import Graphics.Rendering.OGL.GL.Texturing.Specification
+import Graphics.Rendering.OGL.GL.Texturing.Parameters
+import Graphics.Rendering.OGL.GL.Texturing.Objects
+import Graphics.Rendering.OGL.GL.Texturing.Environments
+import Graphics.Rendering.OGL.GL.Texturing.Application
+import Graphics.Rendering.OGL.GL.Texturing.Queries
diff --git a/Graphics/Rendering/OGL/GL/Texturing/Application.hs b/Graphics/Rendering/OGL/GL/Texturing/Application.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Texturing/Application.hs
@@ -0,0 +1,41 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Texturing.Application
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.8.15 (Texture Application) of the
+-- OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Texturing.Application (
+   texture
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( Capability )
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapTexture1D,CapTexture2D,CapTexture3D,CapTextureCubeMap),
+   makeCapability )
+import Graphics.Rendering.OGL.GL.StateVar ( StateVar )
+import Graphics.Rendering.OGL.GL.Texturing.Specification (
+   TextureTarget(..) )
+
+--------------------------------------------------------------------------------
+
+-- ToDo: cube maps
+texture :: TextureTarget -> StateVar Capability
+texture = makeCapability . textureTargetToEnableCap
+
+textureTargetToEnableCap :: TextureTarget -> EnableCap
+textureTargetToEnableCap x = case x of
+    Texture1D -> CapTexture1D
+    Texture2D -> CapTexture2D
+    Texture3D -> CapTexture3D
+    TextureCubeMap -> CapTextureCubeMap
+    TextureRectangle -> error "ToDo: TextureRectangle"
diff --git a/Graphics/Rendering/OGL/GL/Texturing/Environments.hs b/Graphics/Rendering/OGL/GL/Texturing/Environments.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Texturing/Environments.hs
@@ -0,0 +1,366 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Texturing.Environments
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.8.13 (Texture Environments and Texture
+-- Functions) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Texturing.Environments (
+   TextureFunction(..), textureFunction,
+   TextureCombineFunction(..), combineRGB, combineAlpha,
+   ArgNum(..), Arg(..), Src(..), argRGB, argAlpha,
+   rgbScale, alphaScale,
+   constantColor, textureUnitLODBias
+) where
+
+import Control.Monad ( liftM2 )
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Ptr ( Ptr )
+import Foreign.Storable ( Storable )
+import Foreign.Marshal.Utils ( with )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLint, GLenum, GLfloat )
+import Graphics.Rendering.OGL.GL.BlendingFactor (
+   marshalBlendingFactor, unmarshalBlendingFactor )
+import Graphics.Rendering.OGL.GL.PeekPoke ( peek1 )
+import Graphics.Rendering.OGL.GL.PerFragment ( BlendingFactor )
+import Graphics.Rendering.OGL.GL.StateVar (
+   getIO, ($$=), StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.Texturing.Parameters ( LOD )
+import Graphics.Rendering.OGL.GL.Texturing.TextureUnit (
+   marshalTextureUnit, unmarshalTextureUnit )
+import Graphics.Rendering.OGL.GL.VertexSpec( Color4(..), TextureUnit )
+
+--------------------------------------------------------------------------------
+
+data TextureEnvTarget =
+     TextureEnv
+   | TextureFilterControl   -- GL_TEXTURE_LOD_BIAS_EXT
+   | PointSprite            -- GL_COORD_REPLACE_NV
+
+marshalTextureEnvTarget :: TextureEnvTarget -> GLenum
+marshalTextureEnvTarget x = case x of
+   TextureEnv -> 0x2300
+   TextureFilterControl -> 0x8500
+   PointSprite -> 0x8861
+
+--------------------------------------------------------------------------------
+
+data TextureEnvParameter =
+     TexEnvParamTextureEnvMode
+   | TexEnvParamTextureEnvColor
+   | TexEnvParamCombineRGB
+   | TexEnvParamCombineAlpha
+   | TexEnvParamSrc0RGB
+   | TexEnvParamSrc1RGB
+   | TexEnvParamSrc2RGB
+   | TexEnvParamSrc3RGB
+   | TexEnvParamSrc0Alpha
+   | TexEnvParamSrc1Alpha
+   | TexEnvParamSrc2Alpha
+   | TexEnvParamSrc3Alpha
+   | TexEnvParamOperand0RGB
+   | TexEnvParamOperand1RGB
+   | TexEnvParamOperand2RGB
+   | TexEnvParamOperand3RGB
+   | TexEnvParamOperand0Alpha
+   | TexEnvParamOperand1Alpha
+   | TexEnvParamOperand2Alpha
+   | TexEnvParamOperand3Alpha
+   | TexEnvParamRGBScale
+   | TexEnvParamAlphaScale
+   | TexEnvParamLODBias
+
+marshalTextureEnvParameter :: TextureEnvParameter -> GLenum
+marshalTextureEnvParameter x = case x of
+   TexEnvParamTextureEnvMode -> 0x2200
+   TexEnvParamTextureEnvColor -> 0x2201
+   TexEnvParamCombineRGB -> 0x8571
+   TexEnvParamCombineAlpha -> 0x8572
+   TexEnvParamSrc0RGB -> 0x8580
+   TexEnvParamSrc1RGB -> 0x8581
+   TexEnvParamSrc2RGB -> 0x8582
+   TexEnvParamSrc3RGB -> 0x8583
+   TexEnvParamSrc0Alpha -> 0x8588
+   TexEnvParamSrc1Alpha -> 0x8589
+   TexEnvParamSrc2Alpha -> 0x858a
+   TexEnvParamSrc3Alpha -> 0x858b
+   TexEnvParamOperand0RGB -> 0x8590
+   TexEnvParamOperand1RGB -> 0x8591
+   TexEnvParamOperand2RGB -> 0x8592
+   TexEnvParamOperand3RGB -> 0x8593
+   TexEnvParamOperand0Alpha -> 0x8598
+   TexEnvParamOperand1Alpha -> 0x8599
+   TexEnvParamOperand2Alpha -> 0x859a
+   TexEnvParamOperand3Alpha -> 0x859b
+   TexEnvParamRGBScale -> 0x8573
+   TexEnvParamAlphaScale -> 0xd1c
+   TexEnvParamLODBias -> 0x8501
+
+--------------------------------------------------------------------------------
+
+texEnv :: (GLenum -> GLenum -> b -> IO ())
+       -> (a -> (b -> IO ()) -> IO ())
+       -> TextureEnvTarget -> TextureEnvParameter -> a -> IO ()
+texEnv glTexEnv marshalAct t p x =
+   marshalAct x $
+      glTexEnv (marshalTextureEnvTarget t) (marshalTextureEnvParameter p)
+
+foreign import CALLCONV unsafe "glTexEnvi"
+   glTexEnvi :: GLenum -> GLenum ->  GLint -> IO ()
+
+foreign import CALLCONV unsafe "glTexEnvf"
+   glTexEnvf :: GLenum -> GLenum ->  GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glTexEnvfv"
+   glTexEnvC4f :: GLenum -> GLenum -> Ptr (Color4 GLfloat) -> IO ()
+
+--------------------------------------------------------------------------------
+
+getTexEnv :: Storable b
+          => (GLenum -> GLenum -> Ptr b -> IO ())
+          -> (b -> a)
+          -> TextureEnvTarget -> TextureEnvParameter -> IO a
+getTexEnv glGetTexEnv unmarshal t p =
+   alloca $ \buf -> do
+     glGetTexEnv (marshalTextureEnvTarget t) (marshalTextureEnvParameter p) buf
+     peek1 unmarshal buf
+
+foreign import CALLCONV unsafe "glGetTexEnviv"
+   glGetTexEnviv :: GLenum -> GLenum -> Ptr GLint -> IO ()
+
+foreign import CALLCONV unsafe "glGetTexEnvfv"
+   glGetTexEnvfv :: GLenum -> GLenum -> Ptr GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glGetTexEnvfv"
+   glGetTexEnvC4f :: GLenum -> GLenum -> Ptr (Color4 GLfloat) -> IO ()
+
+--------------------------------------------------------------------------------
+
+m2a :: (a -> b) -> a -> (b -> IO ()) -> IO ()
+m2a marshal x act = act (marshal x)
+
+texEnvi ::
+   (GLint -> a) -> (a -> GLint) -> TextureEnvTarget -> TextureEnvParameter -> StateVar a
+texEnvi unmarshal marshal t p =
+   makeStateVar
+      (getTexEnv glGetTexEnviv unmarshal     t p)
+      (texEnv    glTexEnvi     (m2a marshal) t p)
+
+texEnvf ::
+   (GLfloat -> a) -> (a -> GLfloat) -> TextureEnvTarget -> TextureEnvParameter -> StateVar a
+texEnvf unmarshal marshal t p =
+   makeStateVar
+      (getTexEnv glGetTexEnvfv unmarshal     t p)
+      (texEnv    glTexEnvf     (m2a marshal) t p)
+
+texEnvC4f :: TextureEnvTarget -> TextureEnvParameter -> StateVar (Color4 GLfloat)
+texEnvC4f t p =
+   makeStateVar
+      (getTexEnv glGetTexEnvC4f id   t p)
+      (texEnv    glTexEnvC4f    with t p)
+
+--------------------------------------------------------------------------------
+
+data TextureFunction =
+     Modulate
+   | Decal
+   | Blend
+   | Replace
+   | AddUnsigned
+   | Combine
+   | Combine4
+   deriving ( Eq, Ord, Show )
+
+marshalTextureFunction :: TextureFunction -> GLint
+marshalTextureFunction x = case x of
+   Modulate -> 0x2100
+   Decal -> 0x2101
+   Blend -> 0xbe2
+   Replace -> 0x1e01
+   AddUnsigned -> 0x104
+   Combine -> 0x8570
+   Combine4 -> 0x8503
+
+unmarshalTextureFunction :: GLint -> TextureFunction
+unmarshalTextureFunction x
+   | x == 0x2100 = Modulate
+   | x == 0x2101 = Decal
+   | x == 0xbe2 = Blend
+   | x == 0x1e01 = Replace
+   | x == 0x104 = AddUnsigned
+   | x == 0x8570 = Combine
+   | x == 0x8503 = Combine4
+   | otherwise = error ("unmarshalTextureFunction: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+textureFunction :: StateVar TextureFunction
+textureFunction =
+   texEnvi unmarshalTextureFunction marshalTextureFunction TextureEnv TexEnvParamTextureEnvMode
+
+--------------------------------------------------------------------------------
+
+data TextureCombineFunction =
+     Replace'
+   | Modulate'
+   | AddUnsigned'
+   | AddSigned
+   | Interpolate
+   | Subtract
+   | Dot3RGB
+   | Dot3RGBA
+   deriving ( Eq, Ord, Show )
+
+marshalTextureCombineFunction :: TextureCombineFunction -> GLint
+marshalTextureCombineFunction x = case x of
+   Replace' -> 0x1e01
+   Modulate' -> 0x2100
+   AddUnsigned' -> 0x104
+   AddSigned -> 0x8574
+   Interpolate -> 0x8575
+   Subtract -> 0x84e7
+   Dot3RGB -> 0x86ae
+   Dot3RGBA -> 0x86af
+
+unmarshalTextureCombineFunction :: GLint -> TextureCombineFunction
+unmarshalTextureCombineFunction x
+   | x == 0x1e01 = Replace'
+   | x == 0x2100 = Modulate'
+   | x == 0x104 = AddUnsigned'
+   | x == 0x8574 = AddSigned
+   | x == 0x8575 = Interpolate
+   | x == 0x84e7 = Subtract
+   | x == 0x86ae = Dot3RGB
+   | x == 0x86af = Dot3RGBA
+   | otherwise = error ("unmarshalTextureCombineFunction: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+combineRGB :: StateVar TextureCombineFunction
+combineRGB = combine TexEnvParamCombineRGB
+
+combineAlpha :: StateVar TextureCombineFunction
+combineAlpha = combine TexEnvParamCombineAlpha
+
+combine :: TextureEnvParameter -> StateVar TextureCombineFunction
+combine =
+   texEnvi unmarshalTextureCombineFunction marshalTextureCombineFunction TextureEnv
+
+--------------------------------------------------------------------------------
+
+data ArgNum =
+     Arg0
+   | Arg1
+   | Arg2
+   | Arg3
+   deriving ( Eq, Ord, Show )
+
+argNumToOperandRGB :: ArgNum -> TextureEnvParameter
+argNumToOperandRGB x = case x of
+   Arg0 -> TexEnvParamOperand0RGB
+   Arg1 -> TexEnvParamOperand1RGB
+   Arg2 -> TexEnvParamOperand2RGB
+   Arg3 -> TexEnvParamOperand3RGB
+
+argNumToOperandAlpha :: ArgNum -> TextureEnvParameter
+argNumToOperandAlpha x = case x of
+   Arg0 -> TexEnvParamOperand0Alpha
+   Arg1 -> TexEnvParamOperand1Alpha
+   Arg2 -> TexEnvParamOperand2Alpha
+   Arg3 -> TexEnvParamOperand3Alpha
+
+argNumToSrcRGB :: ArgNum -> TextureEnvParameter
+argNumToSrcRGB x = case x of
+   Arg0 -> TexEnvParamSrc0RGB
+   Arg1 -> TexEnvParamSrc1RGB
+   Arg2 -> TexEnvParamSrc2RGB
+   Arg3 -> TexEnvParamSrc3RGB
+
+argNumToSrcAlpha :: ArgNum -> TextureEnvParameter
+argNumToSrcAlpha x = case x of
+   Arg0 -> TexEnvParamSrc0Alpha
+   Arg1 -> TexEnvParamSrc1Alpha
+   Arg2 -> TexEnvParamSrc2Alpha
+   Arg3 -> TexEnvParamSrc3Alpha
+
+--------------------------------------------------------------------------------
+
+data Arg = Arg BlendingFactor Src
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+data Src =
+     CurrentUnit
+   | Previous
+   | Crossbar TextureUnit
+   | Constant
+   | PrimaryColor
+   deriving ( Eq, Ord, Show )
+
+marshalSrc :: Src -> GLint
+marshalSrc x = case x of
+   CurrentUnit -> 0x1702
+   Previous -> 0x8578
+   Crossbar u -> fromIntegral (marshalTextureUnit u)
+   Constant -> 0x8576
+   PrimaryColor -> 0x8577
+
+unmarshalSrc :: GLint -> Src
+unmarshalSrc x
+   | x == 0x1702 = CurrentUnit
+   | x == 0x8578 = Previous
+   | x == 0x8576 = Constant
+   | x == 0x8577 = PrimaryColor
+   | otherwise = Crossbar (unmarshalTextureUnit (fromIntegral x))
+
+--------------------------------------------------------------------------------
+
+argRGB :: ArgNum -> StateVar Arg
+argRGB n = arg (argNumToOperandRGB n) (argNumToSrcRGB n)
+
+argAlpha :: ArgNum -> StateVar Arg
+argAlpha n = arg (argNumToOperandAlpha n) (argNumToSrcAlpha n)
+
+arg :: TextureEnvParameter -> TextureEnvParameter -> StateVar Arg
+arg op src = combineArg (textureEnvOperand op) (textureEnvSrc src)
+   where combineArg v w = makeStateVar
+                             (liftM2 Arg (getIO v) (getIO w))
+                             (\(Arg x y) -> do v $$= x; w $$= y)
+
+textureEnvOperand :: TextureEnvParameter -> StateVar BlendingFactor
+textureEnvOperand =
+   texEnvi (unmarshalBlendingFactor . fromIntegral) (fromIntegral . marshalBlendingFactor) TextureEnv
+
+textureEnvSrc :: TextureEnvParameter -> StateVar Src
+textureEnvSrc = texEnvi unmarshalSrc marshalSrc TextureEnv
+
+--------------------------------------------------------------------------------
+
+rgbScale :: StateVar GLfloat
+rgbScale = scale TexEnvParamRGBScale
+
+alphaScale :: StateVar GLfloat
+alphaScale = scale TexEnvParamAlphaScale
+
+scale :: TextureEnvParameter -> StateVar GLfloat
+scale = texEnvf id id TextureEnv
+
+--------------------------------------------------------------------------------
+
+constantColor :: StateVar (Color4 GLfloat)
+constantColor = texEnvC4f TextureEnv TexEnvParamTextureEnvColor
+
+--------------------------------------------------------------------------------
+
+textureUnitLODBias :: StateVar LOD
+textureUnitLODBias = texEnvf id id TextureFilterControl TexEnvParamLODBias
diff --git a/Graphics/Rendering/OGL/GL/Texturing/Objects.hs b/Graphics/Rendering/OGL/GL/Texturing/Objects.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Texturing/Objects.hs
@@ -0,0 +1,131 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Texturing.Objects
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.8.12 (Texture Objects) of the OpenGL 2.1
+-- specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Texturing.Objects (
+   TextureObject(TextureObject), textureBinding,
+   textureResident, areTexturesResident,
+   TexturePriority, texturePriority, prioritizeTextures
+) where
+
+import Data.List ( partition )
+import Foreign.Marshal.Array ( withArray, withArrayLen, peekArray, allocaArray )
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLboolean, GLuint, GLsizei, GLenum, GLclampf )
+import Graphics.Rendering.OGL.GL.BufferObjects ( ObjectName(..) )
+import Graphics.Rendering.OGL.GL.GLboolean ( unmarshalGLboolean )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetTextureBinding1D,GetTextureBinding2D,GetTextureBinding3D,
+            GetTextureBindingCubeMap,GetTextureBindingRectangle),
+   getEnum1)
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.Texturing.TexParameter (
+   TexParameter(TextureResident,TexturePriority), texParamf, getTexParameteri )
+import Graphics.Rendering.OGL.GL.Texturing.Specification (
+   TextureTarget(..) )
+import Graphics.Rendering.OGL.GL.Texturing.TextureTarget (
+   marshalTextureTarget )
+
+--------------------------------------------------------------------------------
+
+newtype TextureObject = TextureObject { textureID :: GLuint }
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+instance ObjectName TextureObject where
+   genObjectNames n = liftIO . 
+      allocaArray n $ \buf -> do
+        glGenTextures (fromIntegral n) buf
+        fmap (map TextureObject) $ peekArray n buf
+
+   deleteObjectNames textureObjects = liftIO . 
+      withArrayLen (map textureID textureObjects) $
+         glDeleteTextures . fromIntegral
+
+   isObjectName = liftIO . fmap unmarshalGLboolean . glIsTexture . textureID
+
+foreign import CALLCONV unsafe "glGenTextures"
+   glGenTextures :: GLsizei -> Ptr GLuint -> IO ()
+
+foreign import CALLCONV unsafe "glDeleteTextures"
+   glDeleteTextures :: GLsizei -> Ptr GLuint -> IO ()
+
+foreign import CALLCONV unsafe "glIsTexture"
+   glIsTexture :: GLuint -> IO GLboolean
+
+--------------------------------------------------------------------------------
+
+textureBinding :: TextureTarget -> StateVar (Maybe TextureObject)
+textureBinding t =
+   makeStateVar
+      (do o <- getEnum1 TextureObject (textureTargetToGetPName t)
+          return $ if o == defaultTextureObject then Nothing else Just o)
+      (glBindTexture (marshalTextureTarget t) . textureID . (maybe defaultTextureObject id))
+
+defaultTextureObject :: TextureObject
+defaultTextureObject = TextureObject 0
+
+textureTargetToGetPName :: TextureTarget -> GetPName
+textureTargetToGetPName x = case x of
+    Texture1D -> GetTextureBinding1D
+    Texture2D -> GetTextureBinding2D
+    Texture3D -> GetTextureBinding3D
+    TextureCubeMap -> GetTextureBindingCubeMap
+    TextureRectangle -> GetTextureBindingRectangle
+
+foreign import CALLCONV unsafe "glBindTexture"
+   glBindTexture :: GLenum -> GLuint -> IO ()
+
+--------------------------------------------------------------------------------
+
+textureResident :: TextureTarget -> GettableStateVar Bool
+textureResident t =
+   makeGettableStateVar .
+      runGL $ getTexParameteri unmarshalGLboolean t TextureResident
+
+areTexturesResident :: [TextureObject] -> GL ([TextureObject],[TextureObject])
+areTexturesResident texObjs = liftIO $ do
+   withArrayLen (map textureID texObjs) $ \len texObjsBuf ->
+      allocaArray len $ \residentBuf -> do
+         allResident <-
+            glAreTexturesResident (fromIntegral len) texObjsBuf residentBuf
+         if unmarshalGLboolean allResident
+            then return (texObjs, [])
+            else do
+               tr <- fmap (zip texObjs) $ peekArray len residentBuf
+               let (resident, nonResident) = partition (unmarshalGLboolean . snd) tr
+               return (map fst resident, map fst nonResident)
+
+foreign import CALLCONV unsafe "glAreTexturesResident"
+   glAreTexturesResident :: GLsizei -> Ptr GLuint -> Ptr GLboolean -> IO GLboolean
+
+--------------------------------------------------------------------------------
+
+type TexturePriority = GLclampf
+
+texturePriority :: TextureTarget -> StateVar TexturePriority
+texturePriority = texParamf id id TexturePriority
+
+prioritizeTextures :: [(TextureObject,TexturePriority)] -> GL ()
+prioritizeTextures tps = liftIO .
+   withArrayLen (map (textureID . fst) tps) $ \len texObjsBuf ->
+      withArray (map snd tps) $
+         glPrioritizeTextures (fromIntegral len) texObjsBuf
+
+foreign import CALLCONV unsafe "glPrioritizeTextures"
+   glPrioritizeTextures :: GLsizei -> Ptr GLuint -> Ptr GLclampf -> IO ()
diff --git a/Graphics/Rendering/OGL/GL/Texturing/Parameters.hs b/Graphics/Rendering/OGL/GL/Texturing/Parameters.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Texturing/Parameters.hs
@@ -0,0 +1,267 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Texturing.Parameters
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.8.4 (Texture Parameters), section 3.8.7
+-- (Texture Wrap Mode), section 3.8.8 (Texture Minification), and section 3.8.9
+-- (Texture Magnification) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Texturing.Parameters (
+   TextureFilter(..), MinificationFilter, MagnificationFilter, textureFilter,
+   Repetition(..), Clamping(..), textureWrapMode,
+   textureBorderColor, LOD, textureObjectLODBias, maxTextureLODBias,
+   textureLODRange, textureMaxAnisotropy, maxTextureMaxAnisotropy,
+   textureLevelRange, generateMipmap, depthTextureMode, textureCompareMode,
+   textureCompareFailValue, TextureCompareOperator(..), textureCompareOperator
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLint, GLfloat, GLclampf, Capability(..) )
+import Graphics.Rendering.OGL.GL.Capability (
+   marshalCapability, unmarshalCapability )
+import Graphics.Rendering.OGL.GL.ComparisonFunction (
+   marshalComparisonFunction, unmarshalComparisonFunction )
+import Graphics.Rendering.OGL.GL.CoordTrans ( TextureCoordName(..) )
+import Graphics.Rendering.OGL.GL.PerFragment ( ComparisonFunction )
+import Graphics.Rendering.OGL.GL.PixelRectangles (
+   PixelInternalFormat(..) )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetMaxTextureMaxAnisotropy,GetMaxTextureLODBias), getFloat1)
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar,
+   StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.Texturing.Specification (
+   Level, TextureTarget(..) )
+import Graphics.Rendering.OGL.GL.Texturing.TexParameter (
+   TexParameter(TextureMinFilter,TextureMagFilter,TextureWrapS,TextureWrapT,
+                TextureWrapR,TextureBorderColor,TextureMinLOD,TextureMaxLOD,
+                TextureBaseLevel,TextureMaxLevel,TextureMaxAnisotropy,
+                TextureLODBias,GenerateMipmap,DepthTextureMode,
+                TextureCompareMode,TextureCompareFunc,TextureCompareFailValue,
+                TextureCompare,TextureCompareOperator),
+   texParami, texParamf, texParamC4f, combineTexParams, combineTexParamsMaybe )
+import Graphics.Rendering.OGL.GL.Texturing.PixelInternalFormat (
+   marshalPixelInternalFormat, unmarshalPixelInternalFormat )
+import Graphics.Rendering.OGL.GL.VertexSpec( Color4(..) )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal ( recordInvalidEnum )
+
+--------------------------------------------------------------------------------
+
+data TextureFilter =
+     Nearest
+   | Linear'
+   deriving ( Eq, Ord, Show )
+
+type MinificationFilter = (TextureFilter, Maybe TextureFilter)
+
+type MagnificationFilter = TextureFilter
+
+-- We treat MagnificationFilter as a degenerated case of MinificationFilter
+magToMin :: MagnificationFilter -> MinificationFilter
+magToMin magFilter = (magFilter, Nothing)
+
+minToMag :: MinificationFilter -> MagnificationFilter
+minToMag (magFilter, Nothing) = magFilter
+minToMag minFilter = error ("minToMag: illegal value " ++ show minFilter)
+
+marshalMinificationFilter :: MinificationFilter -> GLint
+marshalMinificationFilter x = case x of
+   (Nearest, Nothing     ) -> 0x2600
+   (Linear', Nothing     ) -> 0x2601
+   (Nearest, Just Nearest) -> 0x2700
+   (Linear', Just Nearest) -> 0x2701
+   (Nearest, Just Linear') -> 0x2702
+   (Linear', Just Linear') -> 0x2703
+
+marshalMagnificationFilter :: MagnificationFilter -> GLint
+marshalMagnificationFilter = marshalMinificationFilter . magToMin
+
+unmarshalMinificationFilter :: GLint -> MinificationFilter
+unmarshalMinificationFilter x
+   | x ==  0x2600 = (Nearest, Nothing     )
+   | x ==  0x2601 = (Linear', Nothing     )
+   | x ==  0x2700 = (Nearest, Just Nearest)
+   | x ==  0x2701 = (Linear', Just Nearest)
+   | x ==  0x2702 = (Nearest, Just Linear')
+   | x ==  0x2703 = (Linear', Just Linear')
+   | otherwise = error ("unmarshalMinificationFilter: illegal value " ++ show x)
+
+unmarshalMagnificationFilter :: GLint -> MagnificationFilter
+unmarshalMagnificationFilter = minToMag . unmarshalMinificationFilter
+
+--------------------------------------------------------------------------------
+
+textureFilter :: TextureTarget -> StateVar (MinificationFilter, MagnificationFilter)
+textureFilter =
+   combineTexParams
+      (texParami unmarshalMinificationFilter  marshalMinificationFilter  TextureMinFilter)
+      (texParami unmarshalMagnificationFilter marshalMagnificationFilter TextureMagFilter)
+
+--------------------------------------------------------------------------------
+
+data Repetition =
+     Repeated
+   | Mirrored
+   deriving ( Eq, Ord, Show )
+
+data Clamping =
+     Clamp
+   | Repeat
+   | ClampToEdge
+   | ClampToBorder
+   deriving ( Eq, Ord, Show )
+
+marshalTextureWrapMode :: (Repetition, Clamping) -> GLint
+marshalTextureWrapMode x = case x of
+   (Repeated, Clamp) -> 0x2900
+   (Repeated, Repeat) -> 0x2901
+   (Repeated, ClampToEdge) -> 0x812f
+   (Repeated, ClampToBorder) -> 0x812d
+   (Mirrored, Clamp) -> 0x8742
+   (Mirrored, Repeat) -> 0x8370
+   (Mirrored, ClampToEdge) -> 0x8743
+   (Mirrored, ClampToBorder) -> 0x8912
+
+unmarshalTextureWrapMode :: GLint -> (Repetition, Clamping)
+unmarshalTextureWrapMode x
+   | x == 0x2900 = (Repeated, Clamp)
+   | x == 0x2901 = (Repeated, Repeat)
+   | x == 0x812f = (Repeated, ClampToEdge)
+   | x == 0x812d = (Repeated, ClampToBorder)
+   | x == 0x8742 = (Mirrored, Clamp)
+   | x == 0x8370 = (Mirrored, Repeat)
+   | x == 0x8743 = (Mirrored, ClampToEdge)
+   | x == 0x8912 = (Mirrored, ClampToBorder)
+   | otherwise = error ("unmarshalTextureWrapMode: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+textureWrapMode :: TextureTarget -> TextureCoordName -> StateVar (Repetition,Clamping)
+textureWrapMode t coord = case coord of
+   S -> wrap TextureWrapS
+   T -> wrap TextureWrapT
+   R -> wrap TextureWrapR
+   Q -> invalidTextureCoord
+   where wrap c = texParami unmarshalTextureWrapMode marshalTextureWrapMode c t
+
+invalidTextureCoord :: StateVar (Repetition,Clamping)
+invalidTextureCoord =
+   makeStateVar
+      (do recordInvalidEnum; return (Repeated, Repeat))
+      (const recordInvalidEnum)
+
+--------------------------------------------------------------------------------
+
+textureBorderColor :: TextureTarget -> StateVar (Color4 GLfloat)
+textureBorderColor = texParamC4f TextureBorderColor
+
+--------------------------------------------------------------------------------
+
+type LOD = GLfloat
+
+textureObjectLODBias :: TextureTarget -> StateVar LOD
+textureObjectLODBias = texParamf id id TextureLODBias
+
+maxTextureLODBias :: GettableStateVar LOD
+maxTextureLODBias =
+   makeGettableStateVar (getFloat1 id GetMaxTextureLODBias)
+
+textureLODRange :: TextureTarget -> StateVar (LOD,LOD)
+textureLODRange =
+   combineTexParams
+      (texParamf id id TextureMinLOD)
+      (texParamf id id TextureMaxLOD)
+
+--------------------------------------------------------------------------------
+
+textureMaxAnisotropy :: TextureTarget -> StateVar GLfloat
+textureMaxAnisotropy = texParamf id id TextureMaxAnisotropy
+
+maxTextureMaxAnisotropy :: GettableStateVar GLfloat
+maxTextureMaxAnisotropy =
+   makeGettableStateVar (getFloat1 id GetMaxTextureMaxAnisotropy)
+
+--------------------------------------------------------------------------------
+
+textureLevelRange :: TextureTarget -> StateVar (Level,Level)
+textureLevelRange =
+   combineTexParams
+      (texParami id id TextureBaseLevel)
+      (texParami id id TextureMaxLevel)
+
+--------------------------------------------------------------------------------
+
+generateMipmap :: TextureTarget -> StateVar Capability
+generateMipmap = texParami unmarshal marshal GenerateMipmap
+   where unmarshal = unmarshalCapability . fromIntegral
+         marshal = fromIntegral . marshalCapability
+
+--------------------------------------------------------------------------------
+
+-- Only Luminance', Intensity, and Alpha' allowed
+depthTextureMode :: TextureTarget -> StateVar PixelInternalFormat
+depthTextureMode =
+   texParami unmarshalPixelInternalFormat marshalPixelInternalFormat DepthTextureMode
+
+--------------------------------------------------------------------------------
+
+marshalTextureCompareMode :: Capability -> GLint
+marshalTextureCompareMode x = case x of
+   Disabled -> 0x0     -- i.e. None
+   Enabled -> 0x884e   -- i.e. CompareRToTexture
+
+unmarshalTextureCompareMode :: GLint -> Capability
+unmarshalTextureCompareMode x
+   | x == 0x0 = Disabled
+   | x == 0x884e = Enabled
+   | otherwise = error ("unmarshalTextureCompareMode: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+textureCompareMode :: TextureTarget -> StateVar (Maybe ComparisonFunction)
+textureCompareMode =
+   combineTexParamsMaybe
+      (texParami unmarshalTextureCompareMode marshalTextureCompareMode TextureCompareMode)
+      (texParami unmarshal marshal TextureCompareFunc)
+   where unmarshal = unmarshalComparisonFunction . fromIntegral
+         marshal = fromIntegral . marshalComparisonFunction
+
+--------------------------------------------------------------------------------
+
+textureCompareFailValue :: TextureTarget -> StateVar GLclampf
+textureCompareFailValue = texParamf id id TextureCompareFailValue
+
+--------------------------------------------------------------------------------
+
+data TextureCompareOperator =
+     LequalR
+   | GequalR
+   deriving ( Eq, Ord, Show )
+
+marshalTextureCompareOperator :: TextureCompareOperator -> GLint
+marshalTextureCompareOperator x = case x of
+   LequalR -> 0x819c
+   GequalR -> 0x819d
+
+unmarshalTextureCompareOperator :: GLint -> TextureCompareOperator
+unmarshalTextureCompareOperator x
+   | x == 0x819c = LequalR
+   | x == 0x819d = GequalR
+   | otherwise = error ("unmarshalTextureCompareOperator: illegal value " ++ show x)
+
+--------------------------------------------------------------------------------
+
+textureCompareOperator :: TextureTarget -> StateVar (Maybe TextureCompareOperator)
+textureCompareOperator =
+   combineTexParamsMaybe
+      (texParami (unmarshalCapability . fromIntegral) (fromIntegral. marshalCapability) TextureCompare)
+      (texParami unmarshalTextureCompareOperator marshalTextureCompareOperator TextureCompareOperator)
diff --git a/Graphics/Rendering/OGL/GL/Texturing/PixelInternalFormat.hs b/Graphics/Rendering/OGL/GL/Texturing/PixelInternalFormat.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Texturing/PixelInternalFormat.hs
@@ -0,0 +1,235 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Texturing.PixelInternalFormat
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for (un-)marshaling PixelInternalFormat.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Texturing.PixelInternalFormat (
+   PixelInternalFormat(..), marshalPixelInternalFormat,
+   marshalPixelInternalFormat', unmarshalPixelInternalFormat,
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLint, GLenum )
+
+--------------------------------------------------------------------------------
+
+data PixelInternalFormat =
+     Alpha'
+   | DepthComponent'
+   | Luminance'
+   | LuminanceAlpha'
+   | Intensity
+   | RGB'
+   | RGBA'
+   | SRGB
+   | SRGBAlpha
+   | SLuminance
+   | SLuminanceAlpha
+   | Alpha4
+   | Alpha8
+   | Alpha12
+   | Alpha16
+   | DepthComponent16
+   | DepthComponent24
+   | DepthComponent32
+   | Luminance4
+   | Luminance8
+   | Luminance12
+   | Luminance16
+   | Luminance4Alpha4
+   | Luminance6Alpha2
+   | Luminance8Alpha8
+   | Luminance12Alpha4
+   | Luminance12Alpha12
+   | Luminance16Alpha16
+   | Intensity4
+   | Intensity8
+   | Intensity12
+   | Intensity16
+   | R3G3B2
+   | RGB4
+   | RGB5
+   | RGB8
+   | RGB10
+   | RGB12
+   | RGB16
+   | RGBA2
+   | RGBA4
+   | RGB5A1
+   | RGBA8
+   | RGB10A2
+   | RGBA12
+   | RGBA16
+   | SRGB8
+   | SRGB8Alpha8
+   | SLuminance8
+   | SLuminance8Alpha8
+   | CompressedAlpha
+   | CompressedLuminance
+   | CompressedLuminanceAlpha
+   | CompressedIntensity
+   | CompressedRGB
+   | CompressedRGBA
+   | CompressedSRGB
+   | CompressedSRGBAlpha
+   | CompressedSLuminance
+   | CompressedSLuminanceAlpha
+   deriving ( Eq, Ord, Show )
+
+marshalPixelInternalFormat :: PixelInternalFormat -> GLint
+marshalPixelInternalFormat x = case x of
+   Alpha' -> 0x1906
+   DepthComponent' -> 0x1902
+   Luminance' -> 0x1909
+   LuminanceAlpha' -> 0x190a
+   RGB' -> 0x1907
+   RGBA' -> 0x1908
+   SRGB -> 0x8c40
+   SRGBAlpha -> 0x8c42
+   SLuminance -> 0x8c46
+   SLuminanceAlpha -> 0x8c44
+   Alpha4 -> 0x803b
+   Alpha8 -> 0x803c
+   Alpha12 -> 0x803d
+   Alpha16 -> 0x803e
+   DepthComponent16 -> 0x81a5
+   DepthComponent24 -> 0x81a6
+   DepthComponent32 -> 0x81a7
+   Luminance4 -> 0x803f
+   Luminance8 -> 0x8040
+   Luminance12 -> 0x8041
+   Luminance16 -> 0x8042
+   Luminance4Alpha4 -> 0x8043
+   Luminance6Alpha2 -> 0x8044
+   Luminance8Alpha8 -> 0x8045
+   Luminance12Alpha4 -> 0x8046
+   Luminance12Alpha12 -> 0x8047
+   Luminance16Alpha16 -> 0x8048
+   Intensity -> 0x8049
+   Intensity4 -> 0x804a
+   Intensity8 -> 0x804b
+   Intensity12 -> 0x804c
+   Intensity16 -> 0x804d
+   R3G3B2 -> 0x2a10
+   RGB4 -> 0x804f
+   RGB5 -> 0x8050
+   RGB8 -> 0x8051
+   RGB10 -> 0x8052
+   RGB12 -> 0x8053
+   RGB16 -> 0x8054
+   RGBA2 -> 0x8055
+   RGBA4 -> 0x8056
+   RGB5A1 -> 0x8057
+   RGBA8 -> 0x8058
+   RGB10A2 -> 0x8059
+   RGBA12 -> 0x805a
+   RGBA16 -> 0x805b
+   SRGB8 -> 0x8c41
+   SRGB8Alpha8 -> 0x8c43
+   SLuminance8 -> 0x8c47
+   SLuminance8Alpha8 -> 0x8c45
+   CompressedAlpha -> 0x84e9
+   CompressedLuminance -> 0x84ea
+   CompressedLuminanceAlpha -> 0x84eb
+   CompressedIntensity -> 0x84ec
+   CompressedRGB -> 0x84ed
+   CompressedRGBA -> 0x84ee
+   CompressedSRGB -> 0x8c48
+   CompressedSRGBAlpha -> 0x8c49
+   CompressedSLuminance -> 0x8c4a
+   CompressedSLuminanceAlpha -> 0x8c4b
+
+-- *sigh* The OpenGL API is sometimes a bit creative in its usage of types...
+marshalPixelInternalFormat' :: PixelInternalFormat -> GLenum
+marshalPixelInternalFormat' = fromIntegral . marshalPixelInternalFormat
+
+unmarshalPixelInternalFormat :: GLint -> PixelInternalFormat
+unmarshalPixelInternalFormat x
+   | x == 0x1906 = Alpha'
+   | x == 0x1902 = DepthComponent'
+   | x == 0x1909 = Luminance'
+   | x == 0x190a = LuminanceAlpha'
+   | x == 0x1907 = RGB'
+   | x == 0x1908 = RGBA'
+   | x == 0x8c40 = SRGB
+   | x == 0x8c42 = SRGBAlpha
+   | x == 0x8c46 = SLuminance
+   | x == 0x8c44 = SLuminanceAlpha
+   | x == 0x803b = Alpha4
+   | x == 0x803c = Alpha8
+   | x == 0x803d = Alpha12
+   | x == 0x803e = Alpha16
+   | x == 0x81a5 = DepthComponent16
+   | x == 0x81a6 = DepthComponent24
+   | x == 0x81a7 = DepthComponent32
+   | x == 0x803f = Luminance4
+   | x == 0x8040 = Luminance8
+   | x == 0x8041 = Luminance12
+   | x == 0x8042 = Luminance16
+   | x == 0x8043 = Luminance4Alpha4
+   | x == 0x8044 = Luminance6Alpha2
+   | x == 0x8045 = Luminance8Alpha8
+   | x == 0x8046 = Luminance12Alpha4
+   | x == 0x8047 = Luminance12Alpha12
+   | x == 0x8048 = Luminance16Alpha16
+   | x == 0x8049 = Intensity
+   | x == 0x804a = Intensity4
+   | x == 0x804b = Intensity8
+   | x == 0x804c = Intensity12
+   | x == 0x804d = Intensity16
+   | x == 0x2a10 = R3G3B2
+   | x == 0x804f = RGB4
+   | x == 0x8050 = RGB5
+   | x == 0x8051 = RGB8
+   | x == 0x8052 = RGB10
+   | x == 0x8053 = RGB12
+   | x == 0x8054 = RGB16
+   | x == 0x8055 = RGBA2
+   | x == 0x8056 = RGBA4
+   | x == 0x8057 = RGB5A1
+   | x == 0x8058 = RGBA8
+   | x == 0x8059 = RGB10A2
+   | x == 0x805a = RGBA12
+   | x == 0x805b = RGBA16
+   | x == 0x8c41 = SRGB8
+   | x == 0x8c43 = SRGB8Alpha8
+   | x == 0x8c47 = SLuminance8
+   | x == 0x8c45 = SLuminance8Alpha8
+   | x == 0x84e9 = CompressedAlpha
+   | x == 0x84ea = CompressedLuminance
+   | x == 0x84eb = CompressedLuminanceAlpha
+   | x == 0x84ec = CompressedIntensity
+   | x == 0x84ed = CompressedRGB
+   | x == 0x84ee = CompressedRGBA
+   | x == 0x8c48 = CompressedSRGB
+   | x == 0x8c49 = CompressedSRGBAlpha
+   | x == 0x8c4a = CompressedSLuminance
+   | x == 0x8c4b = CompressedSLuminanceAlpha
+   -- legacy values
+   | x == 1 = Luminance'
+   | x == 2 = LuminanceAlpha'
+   | x == 3 = RGB'
+   | x == 4 = RGBA'
+   | otherwise = error ("unmarshalPixelInternalFormat: illegal value " ++ show x)
+
+-- Note: The following formats are still missing, it's a bit unclear how to
+-- handle these nicely. From the EXT_texture_sRGB spec:
+--
+--    Accepted by the <internalformat> parameter of TexImage2D, CopyTexImage2D,
+--    and CompressedTexImage2DARB and the <format> parameter of
+--    CompressedTexSubImage2DARB:
+--
+--       COMPRESSED_SRGB_S3TC_DXT1_EXT                  0x8C4C
+--       COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT            0x8C4D
+--       COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT            0x8C4E
+--       COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT            0x8C4F
diff --git a/Graphics/Rendering/OGL/GL/Texturing/Queries.hs b/Graphics/Rendering/OGL/GL/Texturing/Queries.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Texturing/Queries.hs
@@ -0,0 +1,162 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Texturing.Queries
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module offers various texture queries.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Texturing.Queries (
+   TextureQuery, textureInternalFormat, textureSize1D, textureSize2D,
+   textureSize3D, textureBorder, textureRGBASizes, textureIntensitySize,
+   textureLuminanceSize, textureIndexSize, textureDepthBits,
+   textureCompressedImageSize, textureProxyOK
+) where
+
+import Control.Monad ( liftM2, liftM3, liftM4 )
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLint, GLsizei, GLenum )
+import Graphics.Rendering.OGL.GL.GLboolean ( unmarshalGLboolean )
+import Graphics.Rendering.OGL.GL.PeekPoke ( peek1 )
+import Graphics.Rendering.OGL.GL.Texturing.PixelInternalFormat (
+   unmarshalPixelInternalFormat )
+import Graphics.Rendering.OGL.GL.PixelRectangles (
+   Proxy(..), PixelInternalFormat(..) )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar )
+import Graphics.Rendering.OGL.GL.Texturing.Specification (
+   TextureTarget(..), CubeMapTarget, Level, Border,
+   TextureSize1D(..), TextureSize2D(..), TextureSize3D(..) )
+import Graphics.Rendering.OGL.GL.Texturing.TextureTarget (
+   marshalProxyTextureTarget, marshalCubeMapTarget )
+import Graphics.Rendering.OGL.GL.VertexSpec( Color4(..) )
+
+--------------------------------------------------------------------------------
+
+data TexLevelParameter =
+     TextureInternalFormat
+   | TextureWidth
+   | TextureHeight
+   | TextureDepth
+   | TextureBorder
+   | TextureRedSize
+   | TextureGreenSize
+   | TextureBlueSize
+   | TextureAlphaSize
+   | TextureIntensitySize
+   | TextureLuminanceSize
+   | TextureIndexSize
+   | DepthBits
+   | TextureCompressedImageSize
+   | TextureCompressed
+
+marshalTexLevelParameter :: TexLevelParameter -> GLenum
+marshalTexLevelParameter x = case x of
+   TextureInternalFormat -> 0x1003
+   TextureWidth -> 0x1000
+   TextureHeight -> 0x1001
+   TextureDepth -> 0x8071
+   TextureBorder -> 0x1005
+   TextureRedSize -> 0x805C
+   TextureGreenSize -> 0x805D
+   TextureBlueSize -> 0x805E
+   TextureAlphaSize -> 0x805F
+   TextureIntensitySize -> 0x8061
+   TextureLuminanceSize -> 0x8060
+   TextureIndexSize -> 0x80ED
+   DepthBits -> 0x0D56
+   TextureCompressedImageSize -> 0x86A0
+   TextureCompressed -> 0x86A1
+
+--------------------------------------------------------------------------------
+
+type TextureQuery a = Either TextureTarget CubeMapTarget -> Level -> GettableStateVar a
+
+textureInternalFormat :: TextureQuery PixelInternalFormat
+textureInternalFormat t level =
+   makeGettableStateVar $
+      getTexLevelParameteri unmarshalPixelInternalFormat NoProxy t level TextureInternalFormat
+
+textureSize1D :: TextureQuery TextureSize1D
+textureSize1D t level =
+   makeGettableStateVar $
+      getTexLevelParameteri (TextureSize1D . fromIntegral) NoProxy t level TextureWidth
+
+textureSize2D :: TextureQuery TextureSize2D
+textureSize2D t level =
+   makeGettableStateVar $
+      liftM2 TextureSize2D
+             (getTexLevelParameteri fromIntegral NoProxy t level TextureWidth )
+             (getTexLevelParameteri fromIntegral NoProxy t level TextureHeight)
+
+textureSize3D :: TextureQuery TextureSize3D
+textureSize3D t level =
+   makeGettableStateVar $
+      liftM3 TextureSize3D
+             (getTexLevelParameteri fromIntegral NoProxy t level TextureWidth )
+             (getTexLevelParameteri fromIntegral NoProxy t level TextureHeight)
+             (getTexLevelParameteri fromIntegral NoProxy t level TextureDepth )
+
+textureBorder :: TextureQuery Border
+textureBorder t level =
+   makeGettableStateVar $
+      getTexLevelParameteri fromIntegral NoProxy t level TextureBorder
+
+textureRGBASizes :: TextureQuery (Color4 GLsizei)
+textureRGBASizes t level =
+   makeGettableStateVar $
+      liftM4 Color4
+             (getTexLevelParameteri fromIntegral NoProxy t level TextureRedSize  )
+             (getTexLevelParameteri fromIntegral NoProxy t level TextureGreenSize)
+             (getTexLevelParameteri fromIntegral NoProxy t level TextureBlueSize )
+             (getTexLevelParameteri fromIntegral NoProxy t level TextureAlphaSize)
+
+textureIntensitySize :: TextureQuery GLsizei
+textureIntensitySize t level =
+   makeGettableStateVar $
+      getTexLevelParameteri fromIntegral NoProxy t level TextureIntensitySize
+
+textureLuminanceSize :: TextureQuery GLsizei
+textureLuminanceSize t level =
+   makeGettableStateVar $
+      getTexLevelParameteri fromIntegral NoProxy t level TextureLuminanceSize
+
+textureIndexSize :: TextureQuery GLsizei
+textureIndexSize t level =
+   makeGettableStateVar $
+      getTexLevelParameteri fromIntegral NoProxy t level TextureIndexSize
+
+textureDepthBits :: TextureQuery GLsizei
+textureDepthBits t level =
+   makeGettableStateVar $
+      getTexLevelParameteri fromIntegral NoProxy t level DepthBits
+
+textureCompressedImageSize :: TextureQuery (Maybe GLsizei)
+textureCompressedImageSize t level =
+   makeGettableStateVar $ do
+      isCompressed <- getTexLevelParameteri unmarshalGLboolean NoProxy t level TextureCompressed
+      if isCompressed
+         then getTexLevelParameteri (Just . fromIntegral) NoProxy t level TextureCompressedImageSize
+         else return Nothing
+
+textureProxyOK :: TextureQuery Bool
+textureProxyOK t level =
+   makeGettableStateVar $
+      getTexLevelParameteri unmarshalGLboolean Proxy t level TextureWidth
+
+getTexLevelParameteri :: (GLint -> a) -> Proxy -> Either TextureTarget CubeMapTarget -> Level -> TexLevelParameter -> IO a
+getTexLevelParameteri f proxy t level p =
+   alloca $ \buf -> do
+      glGetTexLevelParameteriv (either (marshalProxyTextureTarget proxy) (\c -> if proxy == Proxy then marshalProxyTextureTarget Proxy TextureCubeMap else marshalCubeMapTarget c) t) level (marshalTexLevelParameter p) buf
+      peek1 f buf
+
+foreign import CALLCONV unsafe "glGetTexLevelParameteriv"
+   glGetTexLevelParameteriv :: GLenum -> GLint -> GLenum -> Ptr GLint -> IO ()
diff --git a/Graphics/Rendering/OGL/GL/Texturing/Specification.hs b/Graphics/Rendering/OGL/GL/Texturing/Specification.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Texturing/Specification.hs
@@ -0,0 +1,310 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Texturing.Specification
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 3.8.1 (Texture Image Specification),
+-- section 3.8.2 (Alternate Texture Image Specification Commands), and section
+-- 3.8.3 (Compressed Texture Images) of the OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Texturing.Specification (
+   -- * Texture-related Data Types
+   TextureTarget(..), CubeMapTarget(..), Level, Border,
+   TexturePosition1D(..), TexturePosition2D(..), TexturePosition3D(..),
+   TextureSize1D(..), TextureSize2D(..), TextureSize3D(..),
+
+   -- * Texture Image Specification
+   texImage1D, texImage2D, texImage3D,
+   copyTexImage1D, copyTexImage2D,
+   texSubImage1D, texSubImage2D, texSubImage3D,
+   getTexImage,
+
+   -- * Alternate Texture Image Specification Commands
+   copyTexSubImage1D, copyTexSubImage2D, copyTexSubImage3D,
+
+   -- * Compressed Texture Images
+   CompressedTextureFormat(..), compressedTextureFormats,
+   CompressedPixelData(..),
+   compressedTexImage1D, compressedTexImage2D, compressedTexImage3D,
+   compressedTexSubImage1D, compressedTexSubImage2D, compressedTexSubImage3D,
+   getCompressedTexImage
+) where
+
+import Foreign.Marshal.Array ( peekArray, allocaArray )
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLint, GLsizei, GLenum )
+import Graphics.Rendering.OGL.GL.CoordTrans ( Position(..) )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.PixelData ( withPixelData )
+import Graphics.Rendering.OGL.GL.Texturing.PixelInternalFormat (
+   marshalPixelInternalFormat, marshalPixelInternalFormat' )
+import Graphics.Rendering.OGL.GL.PixelRectangles (
+   PixelInternalFormat, PixelData, Proxy(..) )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetNumCompressedTextureFormats,GetCompressedTextureFormats),
+   getInteger1, getIntegerv)
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar )
+import Graphics.Rendering.OGL.GL.Texturing.TextureTarget (
+   TextureTarget(..), marshalTextureTarget, marshalProxyTextureTarget,
+   CubeMapTarget(..), marshalCubeMapTarget )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+
+--------------------------------------------------------------------------------
+
+type Level = GLint
+
+type Border = GLint
+
+newtype TexturePosition1D = TexturePosition1D GLint
+   deriving ( Eq, Ord, Show )
+
+data TexturePosition2D = TexturePosition2D !GLint !GLint
+   deriving ( Eq, Ord, Show )
+
+data TexturePosition3D = TexturePosition3D !GLint !GLint !GLint
+   deriving ( Eq, Ord, Show )
+
+newtype TextureSize1D = TextureSize1D GLsizei
+   deriving ( Eq, Ord, Show )
+
+data TextureSize2D = TextureSize2D !GLsizei !GLsizei
+   deriving ( Eq, Ord, Show )
+
+data TextureSize3D = TextureSize3D !GLsizei !GLsizei !GLsizei
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+texImage1D :: Proxy -> Level -> PixelInternalFormat -> TextureSize1D -> Border -> PixelData a -> GL ()
+texImage1D proxy level int (TextureSize1D w) border pd = liftIO . 
+   withPixelData pd $
+      glTexImage1D
+         (marshalProxyTextureTarget proxy Texture1D)
+         level (marshalPixelInternalFormat int) w border
+
+foreign import CALLCONV unsafe "glTexImage1D"
+   glTexImage1D :: GLenum -> GLint -> GLint -> GLsizei -> GLint -> GLenum -> GLenum -> Ptr a -> IO ()
+
+--------------------------------------------------------------------------------
+
+texImage2D :: Maybe CubeMapTarget -> Proxy -> Level -> PixelInternalFormat -> TextureSize2D -> Border -> PixelData a -> GL ()
+texImage2D mbCubeMap proxy level int (TextureSize2D w h) border pd = liftIO .
+   withPixelData pd $
+      glTexImage2D
+         (maybe (marshalProxyTextureTarget proxy Texture2D)
+                (\c -> if proxy == Proxy then marshalProxyTextureTarget Proxy TextureCubeMap else marshalCubeMapTarget c)
+                mbCubeMap)
+         level (marshalPixelInternalFormat int) w h border
+
+foreign import CALLCONV unsafe "glTexImage2D"
+   glTexImage2D :: GLenum -> GLint -> GLint -> GLsizei -> GLsizei -> GLint -> GLenum -> GLenum -> Ptr a -> IO ()
+
+--------------------------------------------------------------------------------
+
+texImage3D :: Proxy -> Level -> PixelInternalFormat -> TextureSize3D -> Border -> PixelData a -> GL ()
+texImage3D proxy level int (TextureSize3D w h d) border pd = liftIO .
+   withPixelData pd $
+      glTexImage3DEXT
+         (marshalProxyTextureTarget proxy Texture3D)
+         level (marshalPixelInternalFormat int) w h d border
+
+EXTENSION_ENTRY("GL_EXT_texture3D or OpenGL 1.2",glTexImage3DEXT,GLenum -> GLint -> GLint -> GLsizei -> GLsizei -> GLsizei -> GLint -> GLenum -> GLenum -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+getTexImage :: Either TextureTarget CubeMapTarget -> Level -> PixelData a -> GL ()
+getTexImage t level pd = liftIO .
+   withPixelData pd $
+      glGetTexImage (either marshalTextureTarget marshalCubeMapTarget t) level
+
+foreign import CALLCONV unsafe "glGetTexImage"
+   glGetTexImage :: GLenum -> GLint -> GLenum -> GLenum -> Ptr a -> IO ()
+
+--------------------------------------------------------------------------------
+
+copyTexImage1D :: Level -> PixelInternalFormat -> Position -> TextureSize1D -> Border -> GL ()
+copyTexImage1D level int (Position x y) (TextureSize1D w) border = liftIO $
+   glCopyTexImage1D
+      (marshalTextureTarget Texture1D) level
+      (marshalPixelInternalFormat' int) x y w border
+
+foreign import CALLCONV unsafe "glCopyTexImage1D"
+   glCopyTexImage1D :: GLenum -> GLint -> GLenum -> GLint -> GLint -> GLsizei -> GLint -> IO ()
+
+--------------------------------------------------------------------------------
+
+copyTexImage2D :: Maybe CubeMapTarget -> Level -> PixelInternalFormat -> Position -> TextureSize2D -> Border -> GL ()
+copyTexImage2D mbCubeMap level int (Position x y) (TextureSize2D w h) border = liftIO $ 
+   glCopyTexImage2D
+      (maybe (marshalTextureTarget Texture2D) marshalCubeMapTarget mbCubeMap) level
+      (marshalPixelInternalFormat' int) x y w h border
+
+foreign import CALLCONV unsafe "glCopyTexImage2D"
+   glCopyTexImage2D :: GLenum -> GLint -> GLenum -> GLint -> GLint -> GLsizei -> GLsizei -> GLint -> IO ()
+
+--------------------------------------------------------------------------------
+
+texSubImage1D :: Level -> TexturePosition1D -> TextureSize1D -> PixelData a -> GL ()
+texSubImage1D level (TexturePosition1D xOff) (TextureSize1D w) pd = liftIO .
+   withPixelData pd $
+      glTexSubImage1D (marshalTextureTarget Texture1D) level xOff w
+
+foreign import CALLCONV unsafe "glTexSubImage1D"
+   glTexSubImage1D :: GLenum -> GLint -> GLint -> GLsizei -> GLenum -> GLenum -> Ptr a -> IO ()
+
+--------------------------------------------------------------------------------
+
+texSubImage2D :: Maybe CubeMapTarget -> Level -> TexturePosition2D -> TextureSize2D -> PixelData a -> GL ()
+texSubImage2D mbCubeMap level (TexturePosition2D xOff yOff) (TextureSize2D w h) pd = liftIO .
+   withPixelData pd $
+      glTexSubImage2D (maybe (marshalTextureTarget Texture2D) marshalCubeMapTarget mbCubeMap) level xOff yOff w h
+
+foreign import CALLCONV unsafe "glTexSubImage2D"
+   glTexSubImage2D :: GLenum -> GLint -> GLint -> GLint -> GLsizei -> GLsizei -> GLenum -> GLenum -> Ptr a -> IO ()
+
+--------------------------------------------------------------------------------
+
+texSubImage3D :: Level -> TexturePosition3D -> TextureSize3D -> PixelData a -> GL ()
+texSubImage3D level (TexturePosition3D xOff yOff zOff) (TextureSize3D w h d) pd = liftIO .
+   withPixelData pd $
+      glTexSubImage3DEXT (marshalTextureTarget Texture3D) level xOff yOff zOff w h d
+
+EXTENSION_ENTRY("GL_EXT_texture3D or OpenGL 1.2",glTexSubImage3DEXT,GLenum -> GLint -> GLint -> GLint -> GLint -> GLsizei -> GLsizei -> GLsizei -> GLenum -> GLenum -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+copyTexSubImage1D :: Level -> TexturePosition1D -> Position -> TextureSize1D -> GL ()
+copyTexSubImage1D level (TexturePosition1D xOff) (Position x y) (TextureSize1D w) = liftIO $ 
+   glCopyTexSubImage1D (marshalTextureTarget Texture1D) level xOff x y w
+
+foreign import CALLCONV unsafe "glCopyTexSubImage1D"
+   glCopyTexSubImage1D :: GLenum -> GLint -> GLint -> GLint -> GLint -> GLsizei -> IO ()
+
+--------------------------------------------------------------------------------
+
+copyTexSubImage2D :: Maybe CubeMapTarget -> Level -> TexturePosition2D -> Position -> TextureSize2D -> GL ()
+copyTexSubImage2D mbCubeMap level (TexturePosition2D xOff yOff) (Position x y) (TextureSize2D w h) = liftIO $ 
+   glCopyTexSubImage2D (maybe (marshalTextureTarget Texture2D) marshalCubeMapTarget mbCubeMap) level xOff yOff x y w h
+
+foreign import CALLCONV unsafe "glCopyTexSubImage2D"
+   glCopyTexSubImage2D :: GLenum -> GLint -> GLint -> GLint -> GLint -> GLint -> GLsizei -> GLsizei -> IO ()
+
+--------------------------------------------------------------------------------
+
+copyTexSubImage3D :: Level -> TexturePosition3D -> Position -> TextureSize2D -> GL ()
+copyTexSubImage3D level (TexturePosition3D xOff yOff zOff) (Position x y) (TextureSize2D w h) = liftIO $ 
+   glCopyTexSubImage3DEXT (marshalTextureTarget Texture3D) level xOff yOff zOff x y w h
+
+EXTENSION_ENTRY("GL_EXT_texture3D or OpenGL 1.2",glCopyTexSubImage3DEXT,GLenum -> GLint -> GLint -> GLint -> GLint -> GLint -> GLint -> GLsizei -> GLsizei -> IO ())
+
+--------------------------------------------------------------------------------
+
+newtype CompressedTextureFormat = CompressedTextureFormat GLenum
+   deriving ( Eq, Ord, Show )
+
+compressedTextureFormats :: GettableStateVar [CompressedTextureFormat]
+compressedTextureFormats =
+   makeGettableStateVar $ do
+      n <- getInteger1 fromIntegral GetNumCompressedTextureFormats
+      allocaArray n $ \buf -> do
+         getIntegerv GetCompressedTextureFormats buf
+         fmap (map (CompressedTextureFormat . fromIntegral)) $ peekArray n buf
+
+--------------------------------------------------------------------------------
+
+data CompressedPixelData a =
+     CompressedPixelData !CompressedTextureFormat GLsizei (Ptr a)
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq (CompressedPixelData a)
+instance Ord (CompressedPixelData a)
+instance Show (CompressedPixelData a)
+#else
+   deriving ( Eq, Ord, Show )
+#endif
+
+withCompressedPixelData ::
+   CompressedPixelData a -> (GLenum -> GLsizei -> Ptr a -> b) -> b
+withCompressedPixelData
+   (CompressedPixelData (CompressedTextureFormat fmt) size ptr) f =
+   f fmt size ptr
+
+--------------------------------------------------------------------------------
+
+compressedTexImage1D :: Proxy -> Level -> TextureSize1D -> Border -> CompressedPixelData a -> GL ()
+compressedTexImage1D proxy level (TextureSize1D w) border cpd = liftIO .
+   withCompressedPixelData cpd $ \fmt ->
+      glCompressedTexImage1DARB
+         (marshalProxyTextureTarget proxy Texture1D) level fmt w border
+
+EXTENSION_ENTRY("GL_ARB_texture_compression or OpenGL 1.3",glCompressedTexImage1DARB,GLenum -> GLint -> GLenum -> GLsizei -> GLint -> GLsizei -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+compressedTexImage2D :: Maybe CubeMapTarget -> Proxy -> Level -> TextureSize2D -> Border -> CompressedPixelData a -> GL ()
+compressedTexImage2D mbCubeMap proxy level (TextureSize2D w h) border cpd = liftIO .
+   withCompressedPixelData cpd $ \fmt ->
+      glCompressedTexImage2DARB
+         (maybe (marshalProxyTextureTarget proxy Texture2D)
+                (\c -> if proxy == Proxy then marshalProxyTextureTarget Proxy TextureCubeMap else marshalCubeMapTarget c)
+                mbCubeMap)
+         level fmt w h border
+
+EXTENSION_ENTRY("GL_ARB_texture_compression or OpenGL 1.3",glCompressedTexImage2DARB,GLenum -> GLint -> GLenum -> GLsizei -> GLsizei ->GLint -> GLsizei -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+compressedTexImage3D :: Proxy -> Level -> TextureSize3D -> Border -> CompressedPixelData a -> GL ()
+compressedTexImage3D proxy level (TextureSize3D w h d) border cpd = liftIO . 
+   withCompressedPixelData cpd $ \fmt ->
+      glCompressedTexImage3DARB
+         (marshalProxyTextureTarget proxy Texture3D) level fmt w h d border
+
+EXTENSION_ENTRY("GL_ARB_texture_compression or OpenGL 1.3",glCompressedTexImage3DARB,GLenum -> GLint -> GLenum -> GLsizei -> GLsizei -> GLsizei -> GLint -> GLsizei -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+getCompressedTexImage :: Either TextureTarget CubeMapTarget -> Level -> Ptr a -> GL ()
+getCompressedTexImage a b c = liftIO $ glGetCompressedTexImageARB (either marshalTextureTarget marshalCubeMapTarget a) b c
+
+EXTENSION_ENTRY("GL_ARB_texture_compression or OpenGL 1.3",glGetCompressedTexImageARB,GLenum -> GLint -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+compressedTexSubImage1D :: Level -> TexturePosition1D -> TextureSize1D -> CompressedPixelData a -> GL ()
+compressedTexSubImage1D level (TexturePosition1D xOff) (TextureSize1D w) cpd = liftIO .
+   withCompressedPixelData cpd $
+      glCompressedTexSubImage1DARB (marshalTextureTarget Texture1D) level xOff w
+
+EXTENSION_ENTRY("GL_ARB_texture_compression or OpenGL 1.3",glCompressedTexSubImage1DARB,GLenum -> GLint -> GLint -> GLsizei -> GLenum -> GLsizei -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+compressedTexSubImage2D :: Maybe CubeMapTarget -> Level -> TexturePosition2D -> TextureSize2D -> CompressedPixelData a -> GL ()
+compressedTexSubImage2D mbCubeMap level (TexturePosition2D xOff yOff) (TextureSize2D w h) cpd = liftIO .
+   withCompressedPixelData cpd $
+      glCompressedTexSubImage2DARB (maybe (marshalTextureTarget Texture2D) marshalCubeMapTarget mbCubeMap) level xOff yOff w h
+
+EXTENSION_ENTRY("GL_ARB_texture_compression or OpenGL 1.3",glCompressedTexSubImage2DARB,GLenum -> GLint -> GLint -> GLint -> GLsizei -> GLsizei -> GLenum -> GLsizei -> Ptr a-> IO ())
+
+--------------------------------------------------------------------------------
+
+compressedTexSubImage3D :: Level -> TexturePosition3D -> TextureSize3D -> CompressedPixelData a -> GL ()
+compressedTexSubImage3D level (TexturePosition3D xOff yOff zOff) (TextureSize3D w h d) cpd = liftIO .
+   withCompressedPixelData cpd $
+      glCompressedTexSubImage3DARB (marshalTextureTarget Texture3D) level xOff yOff zOff w h d
+
+EXTENSION_ENTRY("GL_ARB_texture_compression or OpenGL 1.3",glCompressedTexSubImage3DARB,GLenum -> GLint -> GLint -> GLint -> GLint -> GLsizei -> GLsizei -> GLsizei -> GLenum -> GLsizei -> Ptr a -> IO ())
diff --git a/Graphics/Rendering/OGL/GL/Texturing/TexParameter.hs b/Graphics/Rendering/OGL/GL/Texturing/TexParameter.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Texturing/TexParameter.hs
@@ -0,0 +1,172 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Texturing.TexParameter
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for getting\/setting texture parameters.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Texturing.TexParameter (
+   TexParameter(..), texParami, texParamf, texParamC4f, getTexParameteri,
+   combineTexParams, combineTexParamsMaybe
+) where
+
+import Control.Monad ( liftM2 )
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Marshal.Utils ( with )
+import Foreign.Storable ( Storable )
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLint, GLenum, GLfloat, Capability(..) )
+import Graphics.Rendering.OGL.GL.PeekPoke ( peek1 )
+import Graphics.Rendering.OGL.GL.StateVar (
+   getIO, ($$=), StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.Texturing.TextureTarget (
+   TextureTarget(..), marshalTextureTarget )
+import Graphics.Rendering.OGL.GL.VertexSpec( Color4(..) )
+
+--------------------------------------------------------------------------------
+
+data TexParameter =
+     TextureMinFilter
+   | TextureMagFilter
+   | TextureWrapS
+   | TextureWrapT
+   | TextureWrapR
+   | TextureBorderColor
+   | TextureMinLOD
+   | TextureMaxLOD
+   | TextureBaseLevel
+   | TextureMaxLevel
+   | TexturePriority
+   | TextureMaxAnisotropy
+   | TextureCompare
+   | TextureCompareOperator
+   | TextureCompareFailValue
+   | GenerateMipmap
+   | TextureCompareMode
+   | TextureCompareFunc
+   | DepthTextureMode
+   | TextureLODBias
+   | TextureResident
+
+marshalTexParameter :: TexParameter -> GLenum
+marshalTexParameter x = case x of
+   TextureMinFilter -> 0x2801
+   TextureMagFilter -> 0x2800
+   TextureWrapS -> 0x2802
+   TextureWrapT -> 0x2803
+   TextureWrapR -> 0x8072
+   TextureBorderColor -> 0x1004
+   TextureMinLOD -> 0x813A
+   TextureMaxLOD -> 0x813B
+   TextureBaseLevel -> 0x813C
+   TextureMaxLevel -> 0x813D
+   TexturePriority -> 0x8066
+   TextureMaxAnisotropy -> 0x84FE
+   TextureCompare -> 0x819A
+   TextureCompareOperator -> 0x819B
+   TextureCompareFailValue -> 0x80BF
+   GenerateMipmap -> 0x8191
+   TextureCompareMode -> 0x884C
+   TextureCompareFunc -> 0x884D
+   DepthTextureMode -> 0x884B
+   TextureLODBias -> 0x8501
+   TextureResident -> 0x8067
+
+--------------------------------------------------------------------------------
+
+texParameter :: (GLenum -> GLenum -> b -> IO ())
+             -> (a -> (b -> IO ()) -> IO ())
+             -> TextureTarget -> TexParameter -> a -> IO ()
+texParameter glTexParameter marshalAct t p x =
+   marshalAct x $
+      glTexParameter (marshalTextureTarget t) (marshalTexParameter p)
+
+foreign import CALLCONV unsafe "glTexParameteri"
+   glTexParameteri :: GLenum -> GLenum ->  GLint -> IO ()
+
+foreign import CALLCONV unsafe "glTexParameterf"
+   glTexParameterf :: GLenum -> GLenum ->  GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glTexParameterfv"
+   glTexParameterC4f :: GLenum -> GLenum -> Ptr (Color4 GLfloat) -> IO ()
+
+--------------------------------------------------------------------------------
+
+getTexParameter :: Storable b
+                => (GLenum -> GLenum -> Ptr b -> IO ())
+                -> (b -> a)
+                -> TextureTarget -> TexParameter -> IO a
+getTexParameter glGetTexParameter unmarshal t p =
+   alloca $ \buf -> do
+     glGetTexParameter (marshalTextureTarget t) (marshalTexParameter p) buf
+     peek1 unmarshal buf
+
+foreign import CALLCONV unsafe "glGetTexParameteriv"
+   glGetTexParameteriv :: GLenum -> GLenum -> Ptr GLint -> IO ()
+
+foreign import CALLCONV unsafe "glGetTexParameterfv"
+   glGetTexParameterfv :: GLenum -> GLenum -> Ptr GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glGetTexParameterfv"
+   glGetTexParameterC4f :: GLenum -> GLenum -> Ptr (Color4 GLfloat) -> IO ()
+
+--------------------------------------------------------------------------------
+
+m2a :: (a -> b) -> a -> (b -> IO ()) -> IO ()
+m2a marshal x act = act (marshal x)
+
+texParami ::
+   (GLint -> a) -> (a -> GLint) -> TexParameter -> TextureTarget -> StateVar a
+texParami unmarshal marshal p t =
+   makeStateVar
+      (getTexParameter glGetTexParameteriv unmarshal     t p)
+      (texParameter    glTexParameteri     (m2a marshal) t p)
+
+texParamf ::
+   (GLfloat -> a) -> (a -> GLfloat) -> TexParameter -> TextureTarget -> StateVar a
+texParamf unmarshal marshal p t =
+   makeStateVar
+      (getTexParameter glGetTexParameterfv unmarshal     t p)
+      (texParameter    glTexParameterf     (m2a marshal) t p)
+
+texParamC4f :: TexParameter -> TextureTarget -> StateVar (Color4 GLfloat)
+texParamC4f p t =
+   makeStateVar
+      (getTexParameter glGetTexParameterC4f id   t p)
+      (texParameter    glTexParameterC4f    with t p)
+
+getTexParameteri :: (GLint -> a) -> TextureTarget -> TexParameter -> GL a
+getTexParameteri a b c = liftIO $ getTexParameter glGetTexParameteriv a b c
+
+--------------------------------------------------------------------------------
+
+combineTexParams :: (TextureTarget -> StateVar a)
+                 -> (TextureTarget -> StateVar b)
+                 -> (TextureTarget -> StateVar (a,b))
+combineTexParams v w t =
+   makeStateVar
+      (liftM2 (,) (getIO (v t)) (getIO (w t)))
+      (\(x,y) -> do v t $$= x; w t $$= y)
+
+combineTexParamsMaybe :: (TextureTarget -> StateVar Capability)
+                      -> (TextureTarget -> StateVar a)
+                      -> (TextureTarget -> StateVar (Maybe a))
+combineTexParamsMaybe enab val t =
+   makeStateVar
+      (do tcm <- getIO (enab t)
+          case tcm of
+             Disabled -> return Nothing
+             Enabled -> fmap Just $ getIO (val t))
+      (maybe (enab t $$= Disabled)
+             (\tcf -> do val t $$= tcf
+                         enab t $$= Enabled))
diff --git a/Graphics/Rendering/OGL/GL/Texturing/TextureTarget.hs b/Graphics/Rendering/OGL/GL/Texturing/TextureTarget.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Texturing/TextureTarget.hs
@@ -0,0 +1,70 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Texturing.TextureTarget
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for marshaling texture targets.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Texturing.TextureTarget (
+   TextureTarget(..), marshalTextureTarget, marshalProxyTextureTarget,
+   CubeMapTarget(..), marshalCubeMapTarget
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum )
+import Graphics.Rendering.OGL.GL.PixelRectangles ( Proxy(..) )
+
+--------------------------------------------------------------------------------
+
+data TextureTarget =
+     Texture1D
+   | Texture2D
+   | Texture3D
+   | TextureCubeMap
+   | TextureRectangle
+   deriving ( Eq, Ord, Show )
+
+marshalTextureTarget :: TextureTarget -> GLenum
+marshalTextureTarget x = case x of
+   Texture1D -> 0xde0
+   Texture2D -> 0xde1
+   Texture3D -> 0x806f
+   TextureCubeMap -> 0x8513
+   TextureRectangle -> 0x84f5
+
+marshalProxyTextureTarget :: Proxy -> TextureTarget -> GLenum
+marshalProxyTextureTarget NoProxy x = marshalTextureTarget x
+marshalProxyTextureTarget Proxy   x = case x of
+   Texture1D -> 0x8063
+   Texture2D -> 0x8064
+   Texture3D -> 0x8070
+   TextureCubeMap -> 0x851b
+   TextureRectangle -> 0x84f7
+
+--------------------------------------------------------------------------------
+
+data CubeMapTarget =
+     TextureCubeMapPositiveX
+   | TextureCubeMapNegativeX
+   | TextureCubeMapPositiveY
+   | TextureCubeMapNegativeY
+   | TextureCubeMapPositiveZ
+   | TextureCubeMapNegativeZ
+   deriving ( Eq, Ord, Show )
+
+marshalCubeMapTarget :: CubeMapTarget -> GLenum
+marshalCubeMapTarget x = case x of
+   TextureCubeMapPositiveX -> 0x8515
+   TextureCubeMapNegativeX -> 0x8516
+   TextureCubeMapPositiveY -> 0x8517
+   TextureCubeMapNegativeY -> 0x8518
+   TextureCubeMapPositiveZ -> 0x8519
+   TextureCubeMapNegativeZ -> 0x851a
diff --git a/Graphics/Rendering/OGL/GL/Texturing/TextureUnit.hs b/Graphics/Rendering/OGL/GL/Texturing/TextureUnit.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/Texturing/TextureUnit.hs
@@ -0,0 +1,35 @@
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.Texturing.TextureUnit
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module for (un-)marshaling TextureUnit.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.Texturing.TextureUnit (
+   TextureUnit(..), marshalTextureUnit, unmarshalTextureUnit
+) where
+
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum, GLuint )
+
+--------------------------------------------------------------------------------
+
+-- | Identifies a texture unit via its number, which must be in the range of
+-- (0 .. 'maxTextureUnit').
+
+newtype TextureUnit = TextureUnit GLuint
+   deriving ( Eq, Ord, Show )
+
+marshalTextureUnit :: TextureUnit -> GLenum
+marshalTextureUnit (TextureUnit x) = 0x84c0 + fromIntegral x
+
+unmarshalTextureUnit :: GLenum -> TextureUnit
+unmarshalTextureUnit x = TextureUnit (fromIntegral (x - 0x84c0))
diff --git a/Graphics/Rendering/OGL/GL/VertexArrays.hs b/Graphics/Rendering/OGL/GL/VertexArrays.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/VertexArrays.hs
@@ -0,0 +1,528 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.VertexArrays
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 2.8 (Vertex Arrays) of the OpenGL 2.1
+-- specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.VertexArrays (
+   -- * Describing Data for the Arrays
+   NumComponents, DataType(..), Stride, VertexArrayDescriptor(..),
+
+   -- * Specifying Data for the Arrays
+   ClientArrayType(..), arrayPointer,
+   InterleavedArrays(..), interleavedArrays,
+
+   -- * Enabling Arrays
+   clientState, clientActiveTexture,
+
+   -- * Dereferencing and Rendering
+   ArrayIndex, NumArrayIndices, NumIndexBlocks,
+   arrayElement, drawArrays, multiDrawArrays, drawElements, multiDrawElements,
+   drawRangeElements, maxElementsVertices, maxElementsIndices, lockArrays,
+   primitiveRestartIndex
+) where
+
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Ptr ( Ptr, nullPtr )
+import Foreign.Storable ( Storable(peek) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.Capability (
+   EnableCap(CapVertexArray,CapNormalArray,CapColorArray,CapIndexArray,
+             CapTextureCoordArray,CapEdgeFlagArray,CapFogCoordArray,
+             CapSecondaryColorArray,CapMatrixIndexArray,CapPrimitiveRestart),
+   makeCapability )
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLboolean, GLenum, GLint, GLuint, GLsizei, Capability(Enabled) )
+import Graphics.Rendering.OGL.GL.DataType (
+   DataType(..), marshalDataType, unmarshalDataType )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetVertexArraySize,GetVertexArrayType,GetVertexArrayStride,
+            GetNormalArrayType,GetNormalArrayStride,GetColorArraySize,
+            GetColorArrayType,GetColorArrayStride,GetSecondaryColorArraySize,
+            GetSecondaryColorArrayType,GetSecondaryColorArrayStride,
+            GetIndexArrayType,GetIndexArrayStride,
+            GetFogCoordArrayType,GetFogCoordArrayStride,
+            GetTextureCoordArraySize,GetTextureCoordArrayType,
+            GetTextureCoordArrayStride,GetEdgeFlagArrayStride,
+            GetMaxElementsVertices,GetMaxElementsIndices,
+            GetClientActiveTexture,GetArrayElementLockFirst,
+            GetArrayElementLockCount,GetPrimitiveRestartIndex),
+   getInteger1, getEnum1, getSizei1 )
+import Graphics.Rendering.OGL.GL.PrimitiveMode ( marshalPrimitiveMode )
+import Graphics.Rendering.OGL.GL.BeginEnd ( PrimitiveMode )
+import Graphics.Rendering.OGL.GL.StateVar (
+   getIO,
+   GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.Texturing.TextureUnit (
+   TextureUnit, marshalTextureUnit, unmarshalTextureUnit )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal (
+   recordInvalidEnum, recordInvalidValue )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+
+--------------------------------------------------------------------------------
+
+type NumComponents = GLint
+
+type Stride = GLsizei
+
+data VertexArrayDescriptor a =
+   VertexArrayDescriptor !NumComponents !DataType !Stride !(Ptr a)
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq (VertexArrayDescriptor a)
+instance Ord (VertexArrayDescriptor a)
+instance Show (VertexArrayDescriptor a)
+#else
+   deriving ( Eq, Ord, Show )
+#endif
+
+noVertexArrayDescriptor :: VertexArrayDescriptor a
+noVertexArrayDescriptor = VertexArrayDescriptor 0 Byte 0 nullPtr
+
+--------------------------------------------------------------------------------
+
+data ClientArrayType =
+     VertexArray
+   | NormalArray
+   | ColorArray
+   | IndexArray
+   | TextureCoordArray
+   | EdgeFlagArray
+   | FogCoordArray
+   | SecondaryColorArray
+   | MatrixIndexArray
+   deriving ( Eq, Ord, Show )
+
+marshalClientArrayType :: ClientArrayType -> GLenum
+marshalClientArrayType x = case x of
+   VertexArray -> 0x8074
+   NormalArray -> 0x8075
+   ColorArray -> 0x8076
+   IndexArray -> 0x8077
+   TextureCoordArray -> 0x8078
+   EdgeFlagArray -> 0x8079
+   FogCoordArray -> 0x8457
+   SecondaryColorArray -> 0x845e
+   MatrixIndexArray -> 0x8844
+
+-- Hmmm...
+clientArrayTypeToEnableCap :: ClientArrayType -> EnableCap
+clientArrayTypeToEnableCap x = case x of
+   VertexArray -> CapVertexArray
+   NormalArray -> CapNormalArray
+   ColorArray -> CapColorArray
+   IndexArray -> CapIndexArray
+   TextureCoordArray -> CapTextureCoordArray
+   EdgeFlagArray -> CapEdgeFlagArray
+   FogCoordArray -> CapFogCoordArray
+   SecondaryColorArray -> CapSecondaryColorArray
+   MatrixIndexArray -> CapMatrixIndexArray
+
+--------------------------------------------------------------------------------
+
+arrayPointer :: ClientArrayType -> StateVar (VertexArrayDescriptor a)
+arrayPointer t = case t of
+   VertexArray -> vertexPointer
+   NormalArray -> normalPointer
+   ColorArray -> colorPointer
+   IndexArray -> indexPointer
+   TextureCoordArray -> texCoordPointer
+   EdgeFlagArray -> edgeFlagPointer
+   FogCoordArray -> fogCoordPointer
+   SecondaryColorArray -> secondaryColorPointer
+   MatrixIndexArray ->
+      makeStateVar
+        (do recordInvalidEnum ; return noVertexArrayDescriptor)
+        (const recordInvalidEnum)
+
+check :: Bool -> IO () -> IO ()
+check flag val = if flag then val else recordInvalidValue
+
+--------------------------------------------------------------------------------
+
+vertexPointer :: StateVar (VertexArrayDescriptor a)
+vertexPointer = makeStateVar getVertexPointer setVertexPointer
+
+getVertexPointer :: IO (VertexArrayDescriptor a)
+getVertexPointer = do
+   n <- getInteger1 id GetVertexArraySize
+   d <- getEnum1 unmarshalDataType GetVertexArrayType
+   s <- getInteger1 fromIntegral GetVertexArrayStride
+   p <- getPointer VertexArrayPointer
+   return $ VertexArrayDescriptor n d s p
+
+setVertexPointer :: VertexArrayDescriptor a -> IO ()
+setVertexPointer (VertexArrayDescriptor n d s p) =
+   glVertexPointer n (marshalDataType d) s p
+
+foreign import CALLCONV unsafe "glVertexPointer" glVertexPointer ::
+   GLint -> GLenum -> GLsizei -> Ptr a -> IO ()
+
+--------------------------------------------------------------------------------
+
+normalPointer :: StateVar (VertexArrayDescriptor a)
+normalPointer = makeStateVar getNormalPointer setNormalPointer
+
+getNormalPointer :: IO (VertexArrayDescriptor a)
+getNormalPointer = do
+   d <- getEnum1 unmarshalDataType GetNormalArrayType
+   s <- getInteger1 fromIntegral GetNormalArrayStride
+   p <- getPointer NormalArrayPointer
+   return $ VertexArrayDescriptor 3 d s p
+
+setNormalPointer :: VertexArrayDescriptor a -> IO ()
+setNormalPointer (VertexArrayDescriptor n d s p) =
+   check (n == 3) $ glNormalPointer (marshalDataType d) s p
+
+foreign import CALLCONV unsafe "glNormalPointer" glNormalPointer ::
+   GLenum -> GLsizei -> Ptr a -> IO ()
+
+--------------------------------------------------------------------------------
+
+colorPointer :: StateVar (VertexArrayDescriptor a)
+colorPointer = makeStateVar getColorPointer setColorPointer
+
+getColorPointer :: IO (VertexArrayDescriptor a)
+getColorPointer = do
+   n <- getInteger1 id GetColorArraySize
+   d <- getEnum1 unmarshalDataType GetColorArrayType
+   s <- getInteger1 fromIntegral GetColorArrayStride
+   p <- getPointer ColorArrayPointer
+   return $ VertexArrayDescriptor n d s p
+
+setColorPointer :: VertexArrayDescriptor a -> IO ()
+setColorPointer (VertexArrayDescriptor n d s p) =
+   check (n == 3 || n == 4) $ glColorPointer n (marshalDataType d) s p
+
+foreign import CALLCONV unsafe "glColorPointer" glColorPointer ::
+   GLint -> GLenum -> GLsizei -> Ptr a -> IO ()
+
+--------------------------------------------------------------------------------
+
+indexPointer :: StateVar (VertexArrayDescriptor a)
+indexPointer = makeStateVar getIndexPointer setIndexPointer
+
+getIndexPointer :: IO (VertexArrayDescriptor a)
+getIndexPointer = do
+   d <- getEnum1 unmarshalDataType GetIndexArrayType
+   s <- getInteger1 fromIntegral GetIndexArrayStride
+   p <- getPointer IndexArrayPointer
+   return $ VertexArrayDescriptor 1 d s p
+
+setIndexPointer :: VertexArrayDescriptor a -> IO ()
+setIndexPointer (VertexArrayDescriptor n d s p) =
+   check (n == 1) $ glIndexPointer (marshalDataType d) s p
+
+foreign import CALLCONV unsafe "glIndexPointer" glIndexPointer ::
+   GLenum -> GLsizei -> Ptr a -> IO ()
+
+--------------------------------------------------------------------------------
+
+texCoordPointer :: StateVar (VertexArrayDescriptor a)
+texCoordPointer = makeStateVar getTexCoordPointer setTexCoordPointer
+
+getTexCoordPointer :: IO (VertexArrayDescriptor a)
+getTexCoordPointer = do
+   n <- getInteger1 id GetTextureCoordArraySize
+   d <- getEnum1 unmarshalDataType GetTextureCoordArrayType
+   s <- getInteger1 fromIntegral GetTextureCoordArrayStride
+   p <- getPointer TextureCoordArrayPointer
+   return $ VertexArrayDescriptor n d s p
+
+setTexCoordPointer :: VertexArrayDescriptor a -> IO ()
+setTexCoordPointer (VertexArrayDescriptor n d s p) =
+   glTexCoordPointer n (marshalDataType d) s p
+
+foreign import CALLCONV unsafe "glTexCoordPointer" glTexCoordPointer ::
+   GLint -> GLenum -> GLsizei -> Ptr a -> IO ()
+
+--------------------------------------------------------------------------------
+
+edgeFlagPointer :: StateVar (VertexArrayDescriptor a)
+edgeFlagPointer = makeStateVar getEdgeFlagPointer setEdgeFlagPointer
+
+getEdgeFlagPointer :: IO (VertexArrayDescriptor a)
+getEdgeFlagPointer = do
+   s <- getInteger1 fromIntegral GetEdgeFlagArrayStride
+   p <- getPointer EdgeFlagArrayPointer
+   return $ VertexArrayDescriptor 1 UnsignedByte s p
+
+setEdgeFlagPointer :: VertexArrayDescriptor a -> IO ()
+setEdgeFlagPointer (VertexArrayDescriptor n d s p) =
+   check (n == 1 && d == UnsignedByte) $ glEdgeFlagPointer s p
+
+foreign import CALLCONV unsafe "glEdgeFlagPointer" glEdgeFlagPointer ::
+   GLsizei -> Ptr a -> IO ()
+
+--------------------------------------------------------------------------------
+
+fogCoordPointer :: StateVar (VertexArrayDescriptor a)
+fogCoordPointer = makeStateVar getFogCoordPointer setFogCoordPointer
+
+getFogCoordPointer :: IO (VertexArrayDescriptor a)
+getFogCoordPointer = do
+   d <- getEnum1 unmarshalDataType GetFogCoordArrayType
+   s <- getInteger1 fromIntegral GetFogCoordArrayStride
+   p <- getPointer FogCoordArrayPointer
+   return $ VertexArrayDescriptor 1 d s p
+
+setFogCoordPointer :: VertexArrayDescriptor a -> IO ()
+setFogCoordPointer (VertexArrayDescriptor n d s p) =
+   check (n == 1) $ glFogCoordPointerEXT (marshalDataType d) s p
+
+EXTENSION_ENTRY("GL_EXT_fog_coord or OpenGL 1.4",glFogCoordPointerEXT,GLenum -> GLsizei -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+secondaryColorPointer :: StateVar (VertexArrayDescriptor a)
+secondaryColorPointer =
+   makeStateVar getSecondaryColorPointer setSecondaryColorPointer
+
+getSecondaryColorPointer :: IO (VertexArrayDescriptor a)
+getSecondaryColorPointer = do
+   n <- getInteger1 id GetSecondaryColorArraySize
+   d <- getEnum1 unmarshalDataType GetSecondaryColorArrayType
+   s <- getInteger1 fromIntegral GetSecondaryColorArrayStride
+   p <- getPointer SecondaryColorArrayPointer
+   return $ VertexArrayDescriptor n d s p
+
+setSecondaryColorPointer :: (VertexArrayDescriptor a) -> IO ()
+setSecondaryColorPointer (VertexArrayDescriptor n d s p) =
+   glSecondaryColorPointerEXT n (marshalDataType d) s p
+
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColorPointerEXT,GLint -> GLenum -> GLsizei -> Ptr a -> IO ())
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttribPointer,GLuint -> GLint -> GLenum -> GLboolean -> GLsizei -> Ptr a -> IO ())
+EXTENSION_ENTRY("OpenGL 2.0",glDisableVertexAttribArray,GLuint -> IO ())
+EXTENSION_ENTRY("OpenGL 2.0",glEnableVertexAttribArray,GLuint -> IO ())
+EXTENSION_ENTRY("OpenGL 2.0",glGetVertexAttribPointerv,GLuint -> GLenum -> Ptr (Ptr a) -> IO ())
+
+--------------------------------------------------------------------------------
+
+data InterleavedArrays =
+     V2f
+   | V3f
+   | C4ubV2f
+   | C4ubV3f
+   | C3fV3f
+   | N3fV3f
+   | C4fN3fV3f
+   | T2fV3f
+   | T4fV4f
+   | T2fC4ubV3f
+   | T2fC3fV3f
+   | T2fN3fV3f
+   | T2fC4fN3fV3f
+   | T4fC4fN3fV4f
+   deriving ( Eq, Ord, Show )
+
+marshalInterleavedArrays :: InterleavedArrays -> GLenum
+marshalInterleavedArrays x = case x of
+   V2f -> 0x2a20
+   V3f -> 0x2a21
+   C4ubV2f -> 0x2a22
+   C4ubV3f -> 0x2a23
+   C3fV3f -> 0x2a24
+   N3fV3f -> 0x2a25
+   C4fN3fV3f -> 0x2a26
+   T2fV3f -> 0x2a27
+   T4fV4f -> 0x2a28
+   T2fC4ubV3f -> 0x2a29
+   T2fC3fV3f -> 0x2a2a
+   T2fN3fV3f -> 0x2a2b
+   T2fC4fN3fV3f -> 0x2a2c
+   T4fC4fN3fV4f -> 0x2a2d
+
+--------------------------------------------------------------------------------
+
+interleavedArrays :: InterleavedArrays -> Stride -> Ptr a -> GL ()
+interleavedArrays = glInterleavedArrays . marshalInterleavedArrays
+
+foreign import CALLCONV unsafe "glInterleavedArrays" glInterleavedArrays ::
+   GLenum -> GLsizei -> Ptr a -> GL ()
+
+--------------------------------------------------------------------------------
+
+clientState :: ClientArrayType -> StateVar Capability
+clientState arrayType =
+   makeStateVar (getClientState arrayType) (setClientState arrayType)
+
+getClientState :: ClientArrayType -> IO Capability
+getClientState = getIO . makeCapability . clientArrayTypeToEnableCap
+
+setClientState :: ClientArrayType -> Capability -> IO ()
+setClientState arrayType val =
+   (if val == Enabled then glEnableClientState else glDisableClientState)
+      (marshalClientArrayType arrayType)
+
+foreign import CALLCONV unsafe "glEnableClientState" glEnableClientState ::
+   GLenum -> IO ()
+
+foreign import CALLCONV unsafe "glDisableClientState" glDisableClientState ::
+   GLenum -> IO ()
+
+--------------------------------------------------------------------------------
+
+clientActiveTexture :: StateVar TextureUnit
+clientActiveTexture =
+   makeStateVar (getEnum1 unmarshalTextureUnit GetClientActiveTexture)
+                (glClientActiveTextureARB . marshalTextureUnit)
+
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glClientActiveTextureARB,GLenum -> IO ())
+
+--------------------------------------------------------------------------------
+
+type ArrayIndex = GLint
+
+type NumArrayIndices = GLsizei
+
+type NumIndexBlocks = GLsizei
+
+--------------------------------------------------------------------------------
+
+arrayElement :: ArrayIndex -> GL ()
+arrayElement = glArrayElement
+
+foreign import CALLCONV unsafe "glArrayElement" glArrayElement :: GLint -> GL ()
+
+drawArrays :: PrimitiveMode -> ArrayIndex -> NumArrayIndices -> GL ()
+drawArrays = glDrawArrays . marshalPrimitiveMode
+
+foreign import CALLCONV unsafe "glDrawArrays" glDrawArrays ::
+   GLenum -> GLint -> GLsizei -> GL ()
+
+multiDrawArrays ::
+      PrimitiveMode -> Ptr ArrayIndex -> Ptr NumArrayIndices -> NumIndexBlocks
+   -> GL ()
+multiDrawArrays = glMultiDrawArraysEXT . marshalPrimitiveMode
+
+EXTENSION_ENTRY("GL_EXT_multi_draw_arrays or OpenGL 1.4",glMultiDrawArraysEXT,GLenum -> Ptr ArrayIndex -> Ptr GLsizei -> GLsizei -> GL ())
+
+drawElements :: PrimitiveMode -> NumArrayIndices -> DataType -> Ptr a -> GL ()
+drawElements m c = glDrawElements (marshalPrimitiveMode m) c . marshalDataType
+
+foreign import CALLCONV unsafe "glDrawElements" glDrawElements ::
+   GLenum -> GLsizei -> GLenum -> Ptr a -> GL ()
+
+multiDrawElements ::
+      PrimitiveMode -> Ptr NumArrayIndices -> DataType -> Ptr (Ptr a)
+   -> NumIndexBlocks -> GL ()
+multiDrawElements m c =
+   glMultiDrawElementsEXT (marshalPrimitiveMode m) c . marshalDataType
+
+EXTENSION_ENTRY("GL_EXT_multi_draw_arrays or OpenGL 1.4",glMultiDrawElementsEXT,GLenum -> Ptr GLsizei -> GLenum -> Ptr (Ptr a) -> GLsizei -> GL ())
+
+drawRangeElements ::
+      PrimitiveMode -> (ArrayIndex, ArrayIndex) -> NumArrayIndices -> DataType
+   -> Ptr a -> GL ()
+drawRangeElements m (s, e) c =
+   glDrawRangeElementsEXT (marshalPrimitiveMode m) (fromIntegral s)
+                          (fromIntegral e) c . marshalDataType
+
+EXTENSION_ENTRY("GL_EXT_draw_range_elements or OpenGL 1.2",glDrawRangeElementsEXT,GLenum -> GLuint -> GLuint -> GLsizei -> GLenum -> Ptr a -> GL ())
+
+maxElementsVertices :: GettableStateVar NumArrayIndices
+maxElementsVertices = makeGettableStateVar (getSizei1 id GetMaxElementsVertices)
+
+maxElementsIndices :: GettableStateVar NumArrayIndices
+maxElementsIndices = makeGettableStateVar (getSizei1 id GetMaxElementsIndices)
+
+--------------------------------------------------------------------------------
+
+lockArrays :: StateVar (Maybe (ArrayIndex, NumArrayIndices))
+lockArrays = makeStateVar getLockArrays setLockArrays
+
+getLockArrays :: IO (Maybe (ArrayIndex, NumArrayIndices))
+getLockArrays = do
+   count <- getInteger1 fromIntegral GetArrayElementLockCount
+   if count > 0
+      then do first <- getInteger1 id GetArrayElementLockFirst
+              return $ Just (first, count)
+      else return Nothing
+
+setLockArrays :: Maybe (ArrayIndex, NumArrayIndices) -> IO ()
+setLockArrays = maybe glUnlockArraysEXT (uncurry glLockArraysEXT)
+
+EXTENSION_ENTRY("GL_EXT_compiled_vertex_array",glLockArraysEXT,GLint -> GLsizei -> IO ())
+EXTENSION_ENTRY("GL_EXT_compiled_vertex_array",glUnlockArraysEXT,IO ())
+
+--------------------------------------------------------------------------------
+
+-- We almost could use makeStateVarMaybe below, but, alas, this is client state.
+
+primitiveRestartIndex :: StateVar (Maybe ArrayIndex)
+primitiveRestartIndex =
+   makeStateVar getPrimitiverestartIndex setPrimitiverestartIndex
+
+getPrimitiverestartIndex :: IO (Maybe ArrayIndex)
+getPrimitiverestartIndex = do
+   state <- getIO (makeCapability CapPrimitiveRestart)
+   if state == Enabled
+      then fmap Just $ getInteger1 fromIntegral GetPrimitiveRestartIndex
+      else return Nothing
+
+setPrimitiverestartIndex :: Maybe ArrayIndex -> IO ()
+setPrimitiverestartIndex maybeIdx = case maybeIdx of
+   Nothing  -> glDisableClientState primitiveRestartNV
+   Just idx -> do glEnableClientState primitiveRestartNV
+                  glPrimitiveRestartIndexNV (fromIntegral idx)
+   where primitiveRestartNV = 0x8558   -- ToDo: HACK!
+
+EXTENSION_ENTRY("GL_NV_primitive_restart",glPrimitiveRestartIndexNV,GLuint -> IO ())
+
+--------------------------------------------------------------------------------
+
+data GetPointervPName =
+     VertexArrayPointer
+   | NormalArrayPointer
+   | ColorArrayPointer
+   | IndexArrayPointer
+   | TextureCoordArrayPointer
+   | EdgeFlagArrayPointer
+   | FogCoordArrayPointer
+   | SecondaryColorArrayPointer
+   | FeedbackBufferPointer
+   | SelectionBufferPointer
+   | WeightArrayPointer
+   | MatrixIndexArrayPointer
+
+marshalGetPointervPName :: GetPointervPName -> GLenum
+marshalGetPointervPName x = case x of
+   VertexArrayPointer -> 0x808e
+   NormalArrayPointer -> 0x808f
+   ColorArrayPointer -> 0x8090
+   IndexArrayPointer -> 0x8091
+   TextureCoordArrayPointer -> 0x8092
+   EdgeFlagArrayPointer -> 0x8093
+   FogCoordArrayPointer -> 0x8456
+   SecondaryColorArrayPointer -> 0x845d
+   FeedbackBufferPointer -> 0xdf0
+   SelectionBufferPointer -> 0xdf3
+   WeightArrayPointer -> 0x86ac
+   MatrixIndexArrayPointer -> 0x8849
+
+--------------------------------------------------------------------------------
+
+getPointer :: GetPointervPName -> IO (Ptr a)
+getPointer n = alloca $ \buf -> do
+   glGetPointerv (marshalGetPointervPName n) buf
+   peek buf
+
+foreign import CALLCONV unsafe "glGetPointerv" glGetPointerv ::
+   GLenum -> Ptr (Ptr a) -> IO ()
diff --git a/Graphics/Rendering/OGL/GL/VertexSpec.hs b/Graphics/Rendering/OGL/GL/VertexSpec.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GL/VertexSpec.hs
@@ -0,0 +1,1400 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GL.VertexSpec
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 2.7 (Vertex Specification) of the
+-- OpenGL 2.1 specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GL.VertexSpec (
+   -- * Vertex Coordinates
+   Vertex(..),
+   VertexComponent,
+   Vertex2(..), Vertex3(..), Vertex4(..),
+
+   -- * Auxiliary Vertex Attributes
+   -- $AuxiliaryVertexAttributes
+
+   -- ** Texture Coordinates
+   currentTextureCoords, TexCoord(..),
+   TexCoordComponent,
+   TexCoord1(..), TexCoord2(..), TexCoord3(..), TexCoord4(..),
+
+   -- ** Normal
+   currentNormal, Normal(..),
+   NormalComponent,
+   Normal3(..),
+
+   -- ** Fog Coordinate
+   currentFogCoord, FogCoord(..),
+   FogCoordComponent,
+   FogCoord1(..),
+
+   -- ** Color and Secondary Color
+   rgbaMode,
+   currentColor, Color(..),
+   currentSecondaryColor, SecondaryColor(..),
+   ColorComponent,
+   Color3(..), Color4(..),
+
+   currentIndex, Index(..),
+   IndexComponent,
+   Index1(..),
+
+   -- * Generic Vertex Attributes
+   AttribLocation(..), VertexAttrib, VertexAttribComponent(..),
+
+   -- * Texture Units
+   TextureUnit(..), maxTextureUnit
+) where
+
+import Data.Int
+import Data.Word
+import Foreign.Ptr ( Ptr, castPtr )
+import Foreign.Storable ( Storable(..) )
+import Foreign.Storable ( Storable(..) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLenum, GLbyte, GLshort, GLint, GLubyte, GLushort, GLuint, GLfloat,
+   GLdouble )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.GLboolean ( unmarshalGLboolean )
+import Graphics.Rendering.OGL.GL.PeekPoke (
+   poke1, poke2, poke3, poke4,
+   peek1, peek2, peek3, peek4 )
+import Graphics.Rendering.OGL.GL.QueryUtils (
+   GetPName(GetCurrentTextureCoords, GetCurrentNormal, GetCurrentFogCoord,
+            GetCurrentColor, GetCurrentSecondaryColor, GetCurrentIndex,
+            GetMaxTextureUnits,GetRGBAMode),
+   getBoolean1, getInteger1, getEnum1, getFloat1, getFloat3, getFloat4 )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar, StateVar, makeStateVar )
+import Graphics.Rendering.OGL.GL.Texturing.TextureUnit (
+   TextureUnit(..), marshalTextureUnit, unmarshalTextureUnit )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+#include "HsOpenGLTypes.h"
+
+--------------------------------------------------------------------------------
+
+-- | The class of all types which can be used as a vertex coordinate.
+
+class VertexComponent a where
+   vertex2 :: a -> a -> PrimitiveGL ()
+   vertex3 :: a -> a -> a -> PrimitiveGL ()
+   vertex4 :: a -> a -> a -> a -> PrimitiveGL ()
+
+   vertex2v :: Ptr a -> PrimitiveGL ()
+   vertex3v :: Ptr a -> PrimitiveGL ()
+   vertex4v :: Ptr a -> PrimitiveGL ()
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glVertex2s" glVertex2s ::
+   GLshort -> GLshort -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex3s" glVertex3s ::
+   GLshort -> GLshort -> GLshort -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex4s" glVertex4s ::
+   GLshort -> GLshort -> GLshort -> GLshort -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex2sv" glVertex2sv ::
+   Ptr GLshort -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex3sv" glVertex3sv ::
+   Ptr GLshort -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex4sv" glVertex4sv ::
+   Ptr GLshort -> PrimitiveGL ()
+
+instance VertexComponent GLshort_ where
+   vertex2 = glVertex2s
+   vertex3 = glVertex3s
+   vertex4 = glVertex4s
+
+   vertex2v = glVertex2sv
+   vertex3v = glVertex3sv
+   vertex4v = glVertex4sv
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glVertex2i" glVertex2i ::
+   GLint -> GLint -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex3i" glVertex3i ::
+   GLint -> GLint -> GLint -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex4i" glVertex4i ::
+   GLint -> GLint -> GLint -> GLint -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex2iv" glVertex2iv ::
+   Ptr GLint -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex3iv" glVertex3iv ::
+   Ptr GLint -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex4iv" glVertex4iv ::
+   Ptr GLint -> PrimitiveGL ()
+
+instance VertexComponent GLint_ where
+   vertex2 = glVertex2i
+   vertex3 = glVertex3i
+   vertex4 = glVertex4i
+
+   vertex2v = glVertex2iv
+   vertex3v = glVertex3iv
+   vertex4v = glVertex4iv
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glVertex2f" glVertex2f ::
+   GLfloat -> GLfloat -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex3f" glVertex3f ::
+   GLfloat -> GLfloat -> GLfloat -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex4f" glVertex4f ::
+   GLfloat -> GLfloat -> GLfloat -> GLfloat -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex2fv" glVertex2fv ::
+   Ptr GLfloat -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex3fv" glVertex3fv ::
+   Ptr GLfloat -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex4fv" glVertex4fv ::
+   Ptr GLfloat -> PrimitiveGL ()
+
+instance VertexComponent GLfloat_ where
+   vertex2 = glVertex2f
+   vertex3 = glVertex3f
+   vertex4 = glVertex4f
+
+   vertex2v = glVertex2fv
+   vertex3v = glVertex3fv
+   vertex4v = glVertex4fv
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glVertex2d" glVertex2d ::
+   GLdouble -> GLdouble -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex3d" glVertex3d ::
+   GLdouble -> GLdouble -> GLdouble -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex4d" glVertex4d ::
+   GLdouble -> GLdouble -> GLdouble -> GLdouble -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex2dv" glVertex2dv ::
+   Ptr GLdouble -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex3dv" glVertex3dv ::
+   Ptr GLdouble -> PrimitiveGL ()
+
+foreign import CALLCONV unsafe "glVertex4dv" glVertex4dv ::
+   Ptr GLdouble -> PrimitiveGL ()
+
+instance VertexComponent GLdouble_ where
+   vertex2 = glVertex2d
+   vertex3 = glVertex3d
+   vertex4 = glVertex4d
+
+   vertex2v = glVertex2dv
+   vertex3v = glVertex3dv
+   vertex4v = glVertex4dv
+
+--------------------------------------------------------------------------------
+
+-- | Specify the (/x/, /y/, /z/, /w/) coordinates of a four-dimensional vertex.
+-- This must only be done during
+-- 'Graphics.Rendering.OGL.GL.BeginEnd.renderPrimitive', otherwise the
+-- behaviour is unspecified. The current values of the auxiliary vertex
+-- attributes are associated with the vertex.
+-- 
+-- Note that there is no such thing as a \"current vertex\" which could be
+-- retrieved.
+
+class Vertex a where
+   vertex  ::     a -> PrimitiveGL ()
+   vertexv :: Ptr a -> PrimitiveGL ()
+
+-- | A vertex with /z/=0 and /w/=1.
+data Vertex2 a = Vertex2 !a !a
+   deriving ( Eq, Ord, Show )
+
+instance VertexComponent a => Vertex (Vertex2 a) where
+   vertex (Vertex2 x y) = vertex2 x y
+   vertexv = vertex2v . (castPtr :: Ptr (Vertex2 b) -> Ptr b)
+
+instance Storable a => Storable (Vertex2 a) where
+   sizeOf    ~(Vertex2 x _) = 2 * sizeOf x
+   alignment ~(Vertex2 x _) = alignment x
+   peek                     = peek2 Vertex2 . castPtr
+   poke ptr   (Vertex2 x y) = poke2 (castPtr ptr) x y
+
+-- | A vertex with /w/=1.
+data Vertex3 a = Vertex3 !a !a !a
+   deriving ( Eq, Ord, Show )
+
+instance VertexComponent a => Vertex (Vertex3 a) where
+   vertex (Vertex3 x y z) = vertex3 x y z
+   vertexv = vertex3v . (castPtr :: Ptr (Vertex3 b) -> Ptr b)
+
+instance Storable a => Storable (Vertex3 a) where
+   sizeOf    ~(Vertex3 x _ _) = 3 * sizeOf x
+   alignment ~(Vertex3 x _ _) = alignment x
+   peek                       = peek3 Vertex3 . castPtr
+   poke ptr   (Vertex3 x y z) = poke3 (castPtr ptr) x y z
+
+-- | A fully-fledged four-dimensional vertex.
+data Vertex4 a = Vertex4 !a !a !a !a
+   deriving ( Eq, Ord, Show )
+
+instance VertexComponent a => Vertex (Vertex4 a) where
+   vertex (Vertex4 x y z w) = vertex4 x y z w
+   vertexv = vertex4v . (castPtr :: Ptr (Vertex4 b) -> Ptr b)
+
+instance Storable a => Storable (Vertex4 a) where
+   sizeOf    ~(Vertex4 x _ _ _) = 4 * sizeOf x
+   alignment ~(Vertex4 x _ _ _) = alignment x
+   peek                         = peek4 Vertex4 . castPtr
+   poke ptr   (Vertex4 x y z w) = poke4 (castPtr ptr) x y z w
+
+--------------------------------------------------------------------------------
+-- $AuxiliaryVertexAttributes
+-- Apart from its coordinates in four-dimensional space, every vertex has
+-- associated /auxiliary attributes/: Its texture coordinates, a normal, a
+-- fog coordinate, and a color plus a secondary color. For every attribute, the
+-- OpenGL state contains its current value, which can be changed at any time.
+--
+-- Every attribute has a \"natural\" format via which it can be manipulated
+-- directly as part of the OpenGL state, e.g. the current texture coordinates
+-- are internally handled as @'TexCoord4' 'GLfloat'@. Different formats are
+-- converted to this format, e.g. the /s/, /r/, and /t/ coordinates of a
+-- @'TexCoord3' 'GLint'@ are converted to floating point values and a /q/
+-- coordinate of 1.0 is implicitly assumed.
+--
+-- Consequently, the vast majority of classes, functions, and data types in this
+-- module are for convenience only and offer no additional functionality.
+
+--------------------------------------------------------------------------------
+
+-- | The current texture coordinates (/s/, /t/, /r/, /q/) for the current
+-- texture unit (see 'Graphics.Rendering.OGL.GL.CoordTrans.activeTexture').
+-- The initial value is (0,0,0,1) for all texture units.
+
+currentTextureCoords :: StateVar (TexCoord4 GLfloat)
+currentTextureCoords =
+   makeStateVar (getFloat4 TexCoord4 GetCurrentTextureCoords) (runPrimitive . texCoord)
+
+--------------------------------------------------------------------------------
+
+-- | The class of all types which can be used as a texture coordinate.
+
+class TexCoordComponent a where
+   texCoord1 :: MonadGL m => a -> m ()
+   texCoord2 :: MonadGL m => a -> a -> m ()
+   texCoord3 :: MonadGL m => a -> a -> a -> m ()
+   texCoord4 :: MonadGL m => a -> a -> a -> a -> m ()
+
+   texCoord1v :: MonadGL m => Ptr a -> m ()
+   texCoord2v :: MonadGL m => Ptr a -> m ()
+   texCoord3v :: MonadGL m => Ptr a -> m ()
+   texCoord4v :: MonadGL m => Ptr a -> m ()
+
+   multiTexCoord1 :: MonadGL m => GLenum -> a -> m ()
+   multiTexCoord2 :: MonadGL m => GLenum -> a -> a -> m ()
+   multiTexCoord3 :: MonadGL m => GLenum -> a -> a -> a -> m ()
+   multiTexCoord4 :: MonadGL m => GLenum -> a -> a -> a -> a -> m ()
+
+   multiTexCoord1v :: MonadGL m => GLenum -> Ptr a -> m ()
+   multiTexCoord2v :: MonadGL m => GLenum -> Ptr a -> m ()
+   multiTexCoord3v :: MonadGL m => GLenum -> Ptr a -> m ()
+   multiTexCoord4v :: MonadGL m => GLenum -> Ptr a -> m ()
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glTexCoord1s" glTexCoord1s :: 
+   GLshort -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord2s" glTexCoord2s ::
+   GLshort -> GLshort -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord3s" glTexCoord3s ::
+   GLshort -> GLshort -> GLshort -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord4s" glTexCoord4s ::
+   GLshort -> GLshort -> GLshort -> GLshort -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord1sv" glTexCoord1sv ::
+   Ptr GLshort -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord2sv" glTexCoord2sv ::
+   Ptr GLshort -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord3sv" glTexCoord3sv ::
+   Ptr GLshort -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord4sv" glTexCoord4sv ::
+   Ptr GLshort -> IO ()
+
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord1sARB,GLenum -> GLshort -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord2sARB,GLenum -> GLshort -> GLshort -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord3sARB,GLenum -> GLshort -> GLshort -> GLshort -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord4sARB,GLenum -> GLshort -> GLshort -> GLshort -> GLshort -> IO ())
+
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord1svARB,GLenum -> Ptr GLshort -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord2svARB,GLenum -> Ptr GLshort -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord3svARB,GLenum -> Ptr GLshort -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord4svARB,GLenum -> Ptr GLshort -> IO ())
+
+instance TexCoordComponent GLshort_ where
+
+   texCoord1         = liftIO . glTexCoord1s
+   texCoord2 a b     = liftIO $ glTexCoord2s a b
+   texCoord3 a b c   = liftIO $ glTexCoord3s a b c
+   texCoord4 a b c d = liftIO $ glTexCoord4s a b c d
+
+   texCoord1v = liftIO . glTexCoord1sv
+   texCoord2v = liftIO . glTexCoord2sv
+   texCoord3v = liftIO . glTexCoord3sv
+   texCoord4v = liftIO . glTexCoord4sv
+
+   multiTexCoord1 x a        = liftIO $ glMultiTexCoord1sARB x a
+   multiTexCoord2 x a b      = liftIO $ glMultiTexCoord2sARB x a b
+   multiTexCoord3 x a b c    = liftIO $ glMultiTexCoord3sARB x a b c 
+   multiTexCoord4 x a b c d  = liftIO $ glMultiTexCoord4sARB x a b c d
+
+   multiTexCoord1v x a = liftIO $ glMultiTexCoord1svARB x a 
+   multiTexCoord2v x a = liftIO $ glMultiTexCoord2svARB x a 
+   multiTexCoord3v x a = liftIO $ glMultiTexCoord3svARB x a 
+   multiTexCoord4v x a = liftIO $ glMultiTexCoord4svARB x a 
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glTexCoord1i" glTexCoord1i ::
+   GLint -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord2i" glTexCoord2i ::
+   GLint -> GLint -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord3i" glTexCoord3i ::
+   GLint -> GLint -> GLint -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord4i" glTexCoord4i ::
+   GLint -> GLint -> GLint -> GLint -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord1iv" glTexCoord1iv ::
+   Ptr GLint -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord2iv" glTexCoord2iv ::
+   Ptr GLint -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord3iv" glTexCoord3iv ::
+   Ptr GLint -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord4iv" glTexCoord4iv ::
+   Ptr GLint -> IO ()
+
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord1iARB,GLenum -> GLint -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord2iARB,GLenum -> GLint -> GLint -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord3iARB,GLenum -> GLint -> GLint -> GLint -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord4iARB,GLenum -> GLint -> GLint -> GLint -> GLint -> IO ())
+
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord1ivARB,GLenum -> Ptr GLint -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord2ivARB,GLenum -> Ptr GLint -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord3ivARB,GLenum -> Ptr GLint -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord4ivARB,GLenum -> Ptr GLint -> IO ())
+
+instance TexCoordComponent GLint_ where
+
+   texCoord1         = liftIO . glTexCoord1i
+   texCoord2 a b     = liftIO $ glTexCoord2i a b
+   texCoord3 a b c   = liftIO $ glTexCoord3i a b c
+   texCoord4 a b c d = liftIO $ glTexCoord4i a b c d
+
+   texCoord1v = liftIO . glTexCoord1iv
+   texCoord2v = liftIO . glTexCoord2iv
+   texCoord3v = liftIO . glTexCoord3iv
+   texCoord4v = liftIO . glTexCoord4iv
+
+   multiTexCoord1 x a        = liftIO $ glMultiTexCoord1iARB x a
+   multiTexCoord2 x a b      = liftIO $ glMultiTexCoord2iARB x a b
+   multiTexCoord3 x a b c    = liftIO $ glMultiTexCoord3iARB x a b c 
+   multiTexCoord4 x a b c d  = liftIO $ glMultiTexCoord4iARB x a b c d
+
+   multiTexCoord1v x a = liftIO $ glMultiTexCoord1ivARB x a 
+   multiTexCoord2v x a = liftIO $ glMultiTexCoord2ivARB x a 
+   multiTexCoord3v x a = liftIO $ glMultiTexCoord3ivARB x a 
+   multiTexCoord4v x a = liftIO $ glMultiTexCoord4ivARB x a 
+   
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glTexCoord1f" glTexCoord1f ::
+   GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord2f" glTexCoord2f ::
+   GLfloat -> GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord3f" glTexCoord3f ::
+   GLfloat -> GLfloat -> GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord4f" glTexCoord4f ::
+   GLfloat -> GLfloat -> GLfloat -> GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord1fv" glTexCoord1fv ::
+   Ptr GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord2fv" glTexCoord2fv ::
+   Ptr GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord3fv" glTexCoord3fv ::
+   Ptr GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord4fv" glTexCoord4fv ::
+   Ptr GLfloat -> IO ()
+
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord1fARB,GLenum -> GLfloat -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord2fARB,GLenum -> GLfloat -> GLfloat -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord3fARB,GLenum -> GLfloat -> GLfloat -> GLfloat -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord4fARB,GLenum -> GLfloat -> GLfloat -> GLfloat -> GLfloat -> IO ())
+
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord1fvARB,GLenum -> Ptr GLfloat -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord2fvARB,GLenum -> Ptr GLfloat -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord3fvARB,GLenum -> Ptr GLfloat -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord4fvARB,GLenum -> Ptr GLfloat -> IO ())
+
+instance TexCoordComponent GLfloat_ where
+
+   texCoord1         = liftIO . glTexCoord1f
+   texCoord2 a b     = liftIO $ glTexCoord2f a b
+   texCoord3 a b c   = liftIO $ glTexCoord3f a b c
+   texCoord4 a b c d = liftIO $ glTexCoord4f a b c d
+
+   texCoord1v = liftIO . glTexCoord1fv
+   texCoord2v = liftIO . glTexCoord2fv
+   texCoord3v = liftIO . glTexCoord3fv
+   texCoord4v = liftIO . glTexCoord4fv
+
+   multiTexCoord1 x a        = liftIO $ glMultiTexCoord1fARB x a
+   multiTexCoord2 x a b      = liftIO $ glMultiTexCoord2fARB x a b
+   multiTexCoord3 x a b c    = liftIO $ glMultiTexCoord3fARB x a b c 
+   multiTexCoord4 x a b c d  = liftIO $ glMultiTexCoord4fARB x a b c d
+
+   multiTexCoord1v x a = liftIO $ glMultiTexCoord1fvARB x a 
+   multiTexCoord2v x a = liftIO $ glMultiTexCoord2fvARB x a 
+   multiTexCoord3v x a = liftIO $ glMultiTexCoord3fvARB x a 
+   multiTexCoord4v x a = liftIO $ glMultiTexCoord4fvARB x a 
+   
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glTexCoord1d" glTexCoord1d ::
+   GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord2d" glTexCoord2d ::
+   GLdouble -> GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord3d" glTexCoord3d ::
+   GLdouble -> GLdouble -> GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord4d" glTexCoord4d ::
+   GLdouble -> GLdouble -> GLdouble -> GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord1dv" glTexCoord1dv ::
+   Ptr GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord2dv" glTexCoord2dv ::
+   Ptr GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord3dv" glTexCoord3dv ::
+   Ptr GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glTexCoord4dv" glTexCoord4dv ::
+   Ptr GLdouble -> IO ()
+
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord1dARB,GLenum -> GLdouble -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord2dARB,GLenum -> GLdouble -> GLdouble -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord3dARB,GLenum -> GLdouble -> GLdouble -> GLdouble -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord4dARB,GLenum -> GLdouble -> GLdouble -> GLdouble -> GLdouble -> IO ())
+
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord1dvARB,GLenum -> Ptr GLdouble -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord2dvARB,GLenum -> Ptr GLdouble -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord3dvARB,GLenum -> Ptr GLdouble -> IO ())
+EXTENSION_ENTRY("GL_ARB_multitexture or OpenGL 1.3",glMultiTexCoord4dvARB,GLenum -> Ptr GLdouble -> IO ())
+
+instance TexCoordComponent GLdouble_ where
+
+   texCoord1         = liftIO . glTexCoord1d
+   texCoord2 a b     = liftIO $ glTexCoord2d a b
+   texCoord3 a b c   = liftIO $ glTexCoord3d a b c
+   texCoord4 a b c d = liftIO $ glTexCoord4d a b c d
+
+   texCoord1v = liftIO . glTexCoord1dv
+   texCoord2v = liftIO . glTexCoord2dv
+   texCoord3v = liftIO . glTexCoord3dv
+   texCoord4v = liftIO . glTexCoord4dv
+
+   multiTexCoord1 x a        = liftIO $ glMultiTexCoord1dARB x a
+   multiTexCoord2 x a b      = liftIO $ glMultiTexCoord2dARB x a b
+   multiTexCoord3 x a b c    = liftIO $ glMultiTexCoord3dARB x a b c 
+   multiTexCoord4 x a b c d  = liftIO $ glMultiTexCoord4dARB x a b c d
+
+   multiTexCoord1v x a = liftIO $ glMultiTexCoord1dvARB x a 
+   multiTexCoord2v x a = liftIO $ glMultiTexCoord2dvARB x a 
+   multiTexCoord3v x a = liftIO $ glMultiTexCoord3dvARB x a 
+   multiTexCoord4v x a = liftIO $ glMultiTexCoord4dvARB x a 
+   
+--------------------------------------------------------------------------------
+
+-- | Change the current texture coordinates of the current or given texture
+-- unit.
+
+class TexCoord a where
+   texCoord       :: MonadGL m =>                    a -> m ()
+   texCoordv      :: MonadGL m =>                Ptr a -> m ()
+   multiTexCoord  :: MonadGL m => TextureUnit ->     a -> m ()
+   multiTexCoordv :: MonadGL m => TextureUnit -> Ptr a -> m ()
+
+-- | Texture coordinates with /t/=0, /r/=0, and /q/=1.
+
+newtype TexCoord1 a = TexCoord1 a
+   deriving ( Eq, Ord, Show )
+
+instance TexCoordComponent a => TexCoord (TexCoord1 a) where
+   texCoord (TexCoord1 s) = texCoord1 s
+   texCoordv = texCoord1v . (castPtr :: Ptr (TexCoord1 b) -> Ptr b)
+   multiTexCoord u (TexCoord1 s) =
+      multiTexCoord1 (marshalTextureUnit u) s
+   multiTexCoordv u =
+      multiTexCoord1v (marshalTextureUnit u) . (castPtr :: Ptr (TexCoord1 b) -> Ptr b)
+
+instance Storable a => Storable (TexCoord1 a) where
+   sizeOf    ~(TexCoord1 s) = sizeOf s
+   alignment ~(TexCoord1 s) = alignment s
+   peek                     = peek1 TexCoord1 . castPtr
+   poke ptr   (TexCoord1 s) = poke1 (castPtr ptr) s
+
+-- | Texture coordinates with /r/=0 and /q/=1.
+
+data TexCoord2 a = TexCoord2 !a !a
+   deriving ( Eq, Ord, Show )
+
+instance TexCoordComponent a => TexCoord (TexCoord2 a) where
+   texCoord (TexCoord2 s t) = texCoord2 s t
+   texCoordv = texCoord2v . (castPtr :: Ptr (TexCoord2 b) -> Ptr b)
+   multiTexCoord u (TexCoord2 s t) =
+      multiTexCoord2 (marshalTextureUnit u) s t
+   multiTexCoordv u =
+      multiTexCoord2v (marshalTextureUnit u) . (castPtr :: Ptr (TexCoord2 b) -> Ptr b)
+
+instance Storable a => Storable (TexCoord2 a) where
+   sizeOf    ~(TexCoord2 s _) = 2 * sizeOf s
+   alignment ~(TexCoord2 s _) = alignment s
+   peek                       = peek2 TexCoord2 . castPtr
+   poke ptr   (TexCoord2 s t) = poke2 (castPtr ptr) s t
+
+-- | Texture coordinates with /q/=1.
+
+data TexCoord3 a = TexCoord3 !a !a !a
+   deriving ( Eq, Ord, Show )
+
+instance TexCoordComponent a => TexCoord (TexCoord3 a) where
+   texCoord (TexCoord3 s t r) = texCoord3 s t r
+   texCoordv = texCoord3v . (castPtr :: Ptr (TexCoord3 b) -> Ptr b)
+   multiTexCoord u (TexCoord3 s t r) =
+      multiTexCoord3 (marshalTextureUnit u) s t r
+   multiTexCoordv u =
+      multiTexCoord3v (marshalTextureUnit u) . (castPtr :: Ptr (TexCoord3 b) -> Ptr b)
+
+instance Storable a => Storable (TexCoord3 a) where
+   sizeOf    ~(TexCoord3 s _ _) = 3 * sizeOf s
+   alignment ~(TexCoord3 s _ _) = alignment s
+   peek                         = peek3 TexCoord3 . castPtr
+   poke ptr   (TexCoord3 s t r) = poke3 (castPtr ptr) s t r
+
+-- | Fully-fledged four-dimensional texture coordinates.
+
+data TexCoord4 a = TexCoord4 !a !a !a !a
+   deriving ( Eq, Ord, Show )
+
+instance TexCoordComponent a => TexCoord (TexCoord4 a) where
+   texCoord (TexCoord4 s t r q) = texCoord4 s t r q
+   texCoordv = texCoord4v . (castPtr :: Ptr (TexCoord4 b) -> Ptr b)
+   multiTexCoord u (TexCoord4 s t r q) =
+      multiTexCoord4 (marshalTextureUnit u) s t r q
+   multiTexCoordv u =
+      multiTexCoord4v (marshalTextureUnit u) . (castPtr :: Ptr (TexCoord4 b) -> Ptr b)
+
+instance Storable a => Storable (TexCoord4 a) where
+   sizeOf    ~(TexCoord4 s _ _ _) = 4 * sizeOf s
+   alignment ~(TexCoord4 s _ _ _) = alignment s
+   peek                           = peek4 TexCoord4 . castPtr
+   poke ptr   (TexCoord4 s t r q) = poke4 (castPtr ptr) s t r q
+
+--------------------------------------------------------------------------------
+
+-- | The current normal (/x/, /y/, /z/). The initial value is the unit vector
+-- (0, 0, 1).
+
+currentNormal :: StateVar (Normal3 GLfloat)
+currentNormal = makeStateVar (getFloat3 Normal3 GetCurrentNormal) (runPrimitive . normal)
+
+--------------------------------------------------------------------------------
+
+-- | The class of all types which can be used as a component of a normal.
+
+class NormalComponent a where
+   normal3  :: MonadGL m => a -> a -> a -> m ()
+   normal3v :: MonadGL m => Ptr a -> m ()
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glNormal3b" glNormal3b ::
+   GLbyte -> GLbyte -> GLbyte -> IO ()
+
+foreign import CALLCONV unsafe "glNormal3bv" glNormal3bv ::
+   Ptr GLbyte -> IO ()
+
+instance NormalComponent GLbyte_ where
+   normal3 a b c = liftIO $ glNormal3b a b c
+   normal3v a    = liftIO $ glNormal3bv a
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glNormal3s" glNormal3s ::
+   GLshort -> GLshort -> GLshort -> IO ()
+
+foreign import CALLCONV unsafe "glNormal3sv" glNormal3sv ::
+   Ptr GLshort -> IO ()
+
+instance NormalComponent GLshort_ where
+   normal3 a b c = liftIO $ glNormal3s a b c
+   normal3v a    = liftIO $ glNormal3sv a
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glNormal3i" glNormal3i ::
+   GLint -> GLint -> GLint -> IO ()
+
+foreign import CALLCONV unsafe "glNormal3iv" glNormal3iv ::
+   Ptr GLint -> IO ()
+
+instance NormalComponent GLint_ where
+   normal3 a b c = liftIO $ glNormal3i a b c
+   normal3v a    = liftIO $ glNormal3iv a
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glNormal3f" glNormal3f ::
+   GLfloat -> GLfloat -> GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glNormal3fv" glNormal3fv ::
+   Ptr GLfloat -> IO ()
+
+instance NormalComponent GLfloat_ where
+   normal3 a b c = liftIO $ glNormal3f a b c
+   normal3v a    = liftIO $ glNormal3fv a
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glNormal3d" glNormal3d ::
+   GLdouble -> GLdouble -> GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glNormal3dv" glNormal3dv ::
+   Ptr GLdouble -> IO ()
+
+instance NormalComponent GLdouble_ where
+   normal3 a b c = liftIO $ glNormal3d a b c
+   normal3v a    = liftIO $ glNormal3dv a
+
+--------------------------------------------------------------------------------
+
+-- | Change the current normal. Integral arguments are converted to
+-- floating-point with a linear mapping that maps the most positive
+-- representable integer value to 1.0, and the most negative representable
+-- integer value to -1.0.
+--
+-- Normals specified with 'normal' or 'normalv' need not have unit length.
+-- If 'Graphics.Rendering.OGL.GL.CoordTrans.normalize' is enabled, then
+-- normals of any length specified with 'normal' or 'normalv' are normalized
+-- after transformation. If
+-- 'Graphics.Rendering.OGL.GL.CoordTrans.rescaleNormal' is enabled, normals
+-- are scaled by a scaling factor derived from the modelview matrix.
+-- 'Graphics.Rendering.OGL.GL.CoordTrans.rescaleNormal' requires that the
+-- originally specified normals were of unit length, and that the modelview
+-- matrix contains only uniform scales for proper results. Normalization is 
+-- initially disabled.
+
+class Normal a where
+   normal  :: MonadGL m =>     a -> m ()
+   normalv :: MonadGL m => Ptr a -> m ()
+
+-- A three-dimensional normal.
+
+data Normal3 a = Normal3 !a !a !a
+   deriving ( Eq, Ord, Show )
+
+instance NormalComponent a => Normal (Normal3 a) where
+   normal (Normal3 x y z) = normal3 x y z
+   normalv = normal3v . (castPtr :: Ptr (Normal3 b) -> Ptr b)
+
+instance Storable a => Storable (Normal3 a) where
+   sizeOf    ~(Normal3 x _ _) = 3 * sizeOf x
+   alignment ~(Normal3 x _ _) = alignment x
+   peek                       = peek3 Normal3 . castPtr
+   poke ptr   (Normal3 x y z) = poke3 (castPtr ptr) x y z
+
+--------------------------------------------------------------------------------
+
+-- | The current fog coordinate. The initial value is 0.
+
+currentFogCoord :: StateVar (FogCoord1 GLfloat)
+currentFogCoord =
+   makeStateVar (getFloat1 FogCoord1 GetCurrentFogCoord) (runPrimitive . fogCoord)
+
+--------------------------------------------------------------------------------
+
+-- | The class of all types which can be used as the fog coordinate.
+
+class FogCoordComponent a where
+   fogCoord1 :: MonadGL m =>      a -> m ()
+   fogCoord1v :: MonadGL m => Ptr a -> m ()
+
+instance Storable a => Storable (FogCoord1 a) where
+   sizeOf    ~(FogCoord1 c) = sizeOf c
+   alignment ~(FogCoord1 c) = alignment c
+   peek                      = peek1 FogCoord1 . castPtr
+   poke ptr   (FogCoord1 c) = poke1 (castPtr ptr) c
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("GL_EXT_fog_coord or OpenGL 1.4",glFogCoordfEXT,GLfloat -> IO ())
+EXTENSION_ENTRY("GL_EXT_fog_coord or OpenGL 1.4",glFogCoordfvEXT,Ptr GLfloat -> IO ())
+
+instance FogCoordComponent GLfloat_ where
+   fogCoord1 = liftIO . glFogCoordfEXT
+   fogCoord1v = liftIO . glFogCoordfvEXT
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("GL_EXT_fog_coord or OpenGL 1.4",glFogCoorddEXT,GLdouble -> IO ())
+EXTENSION_ENTRY("GL_EXT_fog_coord or OpenGL 1.4",glFogCoorddvEXT,Ptr GLdouble -> IO ())
+
+instance FogCoordComponent GLdouble_ where
+   fogCoord1 = liftIO . glFogCoorddEXT
+   fogCoord1v = liftIO . glFogCoorddvEXT
+
+--------------------------------------------------------------------------------
+
+-- | Change the current fog coordinate.
+
+class FogCoord a where
+   fogCoord  :: MonadGL m =>     a -> m ()
+   fogCoordv :: MonadGL m => Ptr a -> m ()
+
+-- | A fog coordinate.
+
+newtype FogCoord1 a = FogCoord1 a
+   deriving ( Eq, Ord, Show )
+
+instance FogCoordComponent a => FogCoord (FogCoord1 a) where
+   fogCoord (FogCoord1 c) = fogCoord1 c
+   fogCoordv = fogCoord1v . (castPtr :: Ptr (FogCoord1 b) -> Ptr b)
+
+--------------------------------------------------------------------------------
+
+-- | If 'rgbaMode' contains 'True', the color buffers store RGBA value. If
+-- color indexes are stored, it contains 'False'.
+
+rgbaMode :: GettableStateVar Bool
+rgbaMode = makeGettableStateVar (getBoolean1 unmarshalGLboolean GetRGBAMode)
+
+--------------------------------------------------------------------------------
+
+-- The current color (/R/, /G/, /B/, /A/). The initial value is (1, 1, 1, 1).
+-- Note that this state variable is significant only when the GL is in RGBA
+-- mode.
+
+currentColor :: StateVar (Color4 GLfloat)
+currentColor =
+   makeStateVar (getFloat4 Color4 GetCurrentColor) (runPrimitive . color)
+
+-- The current secondary color (/R/, /G/, /B/). The initial value is (0, 0, 0).
+-- Note that this state variable is significant only when the GL is in RGBA
+-- mode.
+
+currentSecondaryColor :: StateVar (Color3 GLfloat)
+currentSecondaryColor =
+   makeStateVar
+      (do Color4 r g b _ <- getFloat4 Color4 GetCurrentSecondaryColor
+          return $ Color3 r g b)
+      (runPrimitive . secondaryColor)
+
+--------------------------------------------------------------------------------
+
+-- | The class of all types which can be used as a color component.
+
+class ColorComponent a where
+   color3 :: MonadGL m => a -> a -> a -> m ()
+   color4 :: MonadGL m => a -> a -> a -> a -> m ()
+
+   color3v :: MonadGL m => Ptr a -> m ()
+   color4v :: MonadGL m => Ptr a -> m ()
+
+   secondaryColor3  :: MonadGL m => a -> a -> a -> m ()
+   secondaryColor3v :: MonadGL m => Ptr a -> m ()
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glColor3b" glColor3b ::
+   GLbyte -> GLbyte -> GLbyte -> IO ()
+
+foreign import CALLCONV unsafe "glColor4b" glColor4b ::
+   GLbyte -> GLbyte -> GLbyte -> GLbyte -> IO ()
+
+foreign import CALLCONV unsafe "glColor3bv" glColor3bv ::
+   Ptr GLbyte -> IO ()
+
+foreign import CALLCONV unsafe "glColor4bv" glColor4bv ::
+   Ptr GLbyte -> IO ()
+
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3bEXT,GLbyte -> GLbyte -> GLbyte -> IO ())
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3bvEXT,Ptr GLbyte -> IO ())
+
+instance ColorComponent GLbyte_ where
+   color3 r g b   = liftIO $ glColor3b r g b
+   color4 r g b a = liftIO $ glColor4b r g b a
+
+   color3v = liftIO . glColor3bv
+   color4v = liftIO . glColor4bv
+
+   secondaryColor3 r g b = liftIO $ glSecondaryColor3bEXT r g b
+   secondaryColor3v      = liftIO . glSecondaryColor3bvEXT
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glColor3s" glColor3s ::
+   GLshort -> GLshort -> GLshort -> IO ()
+
+foreign import CALLCONV unsafe "glColor4s" glColor4s ::
+   GLshort -> GLshort -> GLshort -> GLshort -> IO ()
+
+foreign import CALLCONV unsafe "glColor3sv" glColor3sv ::
+   Ptr GLshort -> IO ()
+
+foreign import CALLCONV unsafe "glColor4sv" glColor4sv ::
+   Ptr GLshort -> IO ()
+
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3sEXT,GLshort -> GLshort -> GLshort -> IO ())
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3svEXT,Ptr GLshort -> IO ())
+
+instance ColorComponent GLshort_ where
+
+   color3 r g b   = liftIO $ glColor3s r g b
+   color4 r g b a = liftIO $ glColor4s r g b a
+
+   color3v = liftIO . glColor3sv
+   color4v = liftIO . glColor4sv
+
+   secondaryColor3 r g b = liftIO $ glSecondaryColor3sEXT r g b
+   secondaryColor3v      = liftIO . glSecondaryColor3svEXT
+   
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glColor3i" glColor3i ::
+   GLint -> GLint -> GLint -> IO ()
+
+foreign import CALLCONV unsafe "glColor4i" glColor4i ::
+   GLint -> GLint -> GLint -> GLint -> IO ()
+
+foreign import CALLCONV unsafe "glColor3iv" glColor3iv ::
+   Ptr GLint -> IO ()
+
+foreign import CALLCONV unsafe "glColor4iv" glColor4iv ::
+   Ptr GLint -> IO ()
+
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3iEXT,GLint -> GLint -> GLint -> IO ())
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3ivEXT,Ptr GLint -> IO ())
+
+instance ColorComponent GLint_ where
+
+   color3 r g b   = liftIO $ glColor3i r g b
+   color4 r g b a = liftIO $ glColor4i r g b a
+
+   color3v = liftIO . glColor3iv
+   color4v = liftIO . glColor4iv
+
+   secondaryColor3 r g b = liftIO $ glSecondaryColor3iEXT r g b
+   secondaryColor3v      = liftIO . glSecondaryColor3ivEXT
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glColor3f" glColor3f ::
+   GLfloat -> GLfloat -> GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glColor4f" glColor4f ::
+   GLfloat -> GLfloat -> GLfloat -> GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glColor3fv" glColor3fv ::
+   Ptr GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glColor4fv" glColor4fv ::
+   Ptr GLfloat -> IO ()
+
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3fEXT,GLfloat -> GLfloat -> GLfloat -> IO ())
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3fvEXT,Ptr GLfloat -> IO ())
+
+instance ColorComponent GLfloat_ where
+   color3 r g b   = liftIO $ glColor3f r g b
+   color4 r g b a = liftIO $ glColor4f r g b a
+
+   color3v = liftIO . glColor3fv
+   color4v = liftIO . glColor4fv
+
+   secondaryColor3 r g b = liftIO $ glSecondaryColor3fEXT r g b
+   secondaryColor3v      = liftIO . glSecondaryColor3fvEXT
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glColor3d" glColor3d ::
+   GLdouble -> GLdouble -> GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glColor4d" glColor4d ::
+   GLdouble -> GLdouble -> GLdouble -> GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glColor3dv" glColor3dv ::
+   Ptr GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glColor4dv" glColor4dv ::
+   Ptr GLdouble -> IO ()
+
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3dEXT,GLdouble -> GLdouble -> GLdouble -> IO ())
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3dvEXT,Ptr GLdouble -> IO ())
+
+instance ColorComponent GLdouble_ where
+   color3 r g b   = liftIO $ glColor3d r g b
+   color4 r g b a = liftIO $ glColor4d r g b a
+
+   color3v = liftIO . glColor3dv
+   color4v = liftIO . glColor4dv
+
+   secondaryColor3 r g b = liftIO $ glSecondaryColor3dEXT r g b
+   secondaryColor3v      = liftIO . glSecondaryColor3dvEXT
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glColor3ub" glColor3ub ::
+   GLubyte -> GLubyte -> GLubyte -> IO ()
+
+foreign import CALLCONV unsafe "glColor4ub" glColor4ub ::
+   GLubyte -> GLubyte -> GLubyte -> GLubyte -> IO ()
+
+
+foreign import CALLCONV unsafe "glColor3ubv" glColor3ubv ::
+   Ptr GLubyte -> IO ()
+
+foreign import CALLCONV unsafe "glColor4ubv" glColor4ubv ::
+   Ptr GLubyte -> IO ()
+
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3ubEXT,GLubyte -> GLubyte -> GLubyte -> IO ())
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3ubvEXT,Ptr GLubyte -> IO ())
+
+instance ColorComponent GLubyte_ where
+   color3 r g b   = liftIO $ glColor3ub r g b
+   color4 r g b a = liftIO $ glColor4ub r g b a
+
+   color3v = liftIO . glColor3ubv
+   color4v = liftIO . glColor4ubv
+
+   secondaryColor3 r g b = liftIO $ glSecondaryColor3ubEXT r g b
+   secondaryColor3v      = liftIO . glSecondaryColor3ubvEXT
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glColor3us" glColor3us ::
+   GLushort -> GLushort -> GLushort -> IO ()
+
+foreign import CALLCONV unsafe "glColor4us" glColor4us ::
+   GLushort -> GLushort -> GLushort -> GLushort -> IO ()
+
+foreign import CALLCONV unsafe "glColor3usv" glColor3usv ::
+   Ptr GLushort -> IO ()
+
+foreign import CALLCONV unsafe "glColor4usv" glColor4usv ::
+   Ptr GLushort -> IO ()
+
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3usEXT,GLushort -> GLushort -> GLushort -> IO ())
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3usvEXT,Ptr GLushort -> IO ())
+
+instance ColorComponent GLushort_ where
+   color3 r g b   = liftIO $ glColor3us r g b
+   color4 r g b a = liftIO $ glColor4us r g b a
+
+   color3v = liftIO . glColor3usv
+   color4v = liftIO . glColor4usv
+
+   secondaryColor3 r g b = liftIO $ glSecondaryColor3usEXT r g b
+   secondaryColor3v      = liftIO . glSecondaryColor3usvEXT
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glColor3ui" glColor3ui ::
+   GLuint -> GLuint -> GLuint -> IO ()
+
+foreign import CALLCONV unsafe "glColor4ui" glColor4ui ::
+   GLuint -> GLuint -> GLuint -> GLuint -> IO ()
+
+foreign import CALLCONV unsafe "glColor3uiv" glColor3uiv ::
+   Ptr GLuint -> IO ()
+
+foreign import CALLCONV unsafe "glColor4uiv" glColor4uiv ::
+   Ptr GLuint -> IO ()
+
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3uiEXT,GLuint -> GLuint -> GLuint -> IO ())
+EXTENSION_ENTRY("GL_EXT_secondary_color or OpenGL 1.4",glSecondaryColor3uivEXT,Ptr GLuint -> IO ())
+
+instance ColorComponent GLuint_ where
+   color3 r g b   = liftIO $ glColor3ui r g b
+   color4 r g b a = liftIO $ glColor4ui r g b a
+
+   color3v = liftIO . glColor3uiv
+   color4v = liftIO . glColor4uiv
+
+   secondaryColor3 r g b = liftIO $ glSecondaryColor3uiEXT r g b
+   secondaryColor3v      = liftIO . glSecondaryColor3uivEXT
+
+--------------------------------------------------------------------------------
+
+-- | Change the current color.
+
+class Color a where
+   color  :: MonadGL m =>     a -> m ()
+   colorv :: MonadGL m => Ptr a -> m ()
+
+-- An RGBA color with /A/=1.
+
+data Color3 a = Color3 !a !a !a
+   deriving ( Eq, Ord, Show )
+
+instance ColorComponent a => Color (Color3 a) where
+   color (Color3 r g b) = color3 r g b
+   colorv = color3v . (castPtr :: Ptr (Color3 b) -> Ptr b)
+
+instance Storable a => Storable (Color3 a) where
+   sizeOf    ~(Color3 r _ _) = 3 * sizeOf r
+   alignment ~(Color3 r _ _) = alignment r
+   peek                      = peek3 Color3 . castPtr
+   poke ptr   (Color3 r g b) = poke3 (castPtr ptr) r g b
+
+-- | A fully-fledged RGBA color.
+
+data Color4 a = Color4 !a !a !a !a
+   deriving ( Eq, Ord, Show )
+
+instance ColorComponent a => Color (Color4 a) where
+   color (Color4 r g b a) = color4 r g b a
+   colorv = color4v . (castPtr :: Ptr (Color4 b) -> Ptr b)
+
+instance Storable a => Storable (Color4 a) where
+   sizeOf    ~(Color4 r _ _ _) = 4 * sizeOf r
+   alignment ~(Color4 r _ _ _) = alignment r
+   peek                        = peek4 Color4 . castPtr
+   poke ptr   (Color4 r g b a) = poke4 (castPtr ptr) r g b a
+
+--------------------------------------------------------------------------------
+
+-- | Change the current secondary color.
+
+class SecondaryColor a where
+   secondaryColor  :: MonadGL m =>     a -> m ()
+   secondaryColorv :: MonadGL m => Ptr a -> m ()
+
+instance ColorComponent a => SecondaryColor (Color3 a) where
+   secondaryColor (Color3 r g b) = secondaryColor3 r g b
+   secondaryColorv = secondaryColor3v . (castPtr :: Ptr (Color3 b) -> Ptr b)
+
+--------------------------------------------------------------------------------
+
+-- The current color index. The initial value is 1. Note that this state
+-- variable is significant only when the GL is in color index mode.
+
+currentIndex :: StateVar (Index1 GLint)
+currentIndex = makeStateVar (getInteger1 Index1 GetCurrentIndex) (runPrimitive . index)
+
+--------------------------------------------------------------------------------
+
+-- | The class of all types which can be used as a color index.
+
+class IndexComponent a where
+   index1  :: MonadGL m => a -> m ()
+   index1v :: MonadGL m => Ptr a -> m ()
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glIndexs" glIndexs ::
+   GLshort -> IO ()
+
+foreign import CALLCONV unsafe "glIndexsv" glIndexsv ::
+   Ptr GLshort -> IO ()
+
+instance IndexComponent GLshort_ where
+   index1 = liftIO . glIndexs
+   index1v = liftIO . glIndexsv
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glIndexi" glIndexi ::
+   GLint -> IO ()
+
+foreign import CALLCONV unsafe "glIndexiv" glIndexiv ::
+   Ptr GLint -> IO ()
+
+instance IndexComponent GLint_ where
+   index1 = liftIO . glIndexi
+   index1v = liftIO . glIndexiv
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glIndexf" glIndexf ::
+   GLfloat -> IO ()
+
+foreign import CALLCONV unsafe "glIndexfv" glIndexfv ::
+   Ptr GLfloat -> IO ()
+
+instance IndexComponent GLfloat_ where
+   index1 = liftIO . glIndexf
+   index1v = liftIO . glIndexfv
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glIndexd" glIndexd ::
+   GLdouble -> IO ()
+
+foreign import CALLCONV unsafe "glIndexdv" glIndexdv ::
+   Ptr GLdouble -> IO ()
+
+instance IndexComponent GLdouble_ where
+   index1 = liftIO . glIndexd
+   index1v = liftIO . glIndexdv
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "glIndexub" glIndexub ::
+   GLubyte -> IO ()
+
+foreign import CALLCONV unsafe "glIndexubv" glIndexubv ::
+   Ptr GLubyte -> IO ()
+
+instance IndexComponent GLubyte_ where
+   index1 = liftIO . glIndexub
+   index1v = liftIO . glIndexubv
+
+--------------------------------------------------------------------------------
+
+-- | Change the current color index.
+
+class Index a where
+   index  :: MonadGL m =>     a -> m ()  -- Collision with Prelude.index
+   indexv :: MonadGL m => Ptr a -> m ()
+
+-- | A color index.
+
+newtype Index1 a = Index1 a
+   deriving ( Eq, Ord, Show )
+
+instance IndexComponent a => Index (Index1 a) where
+   index (Index1 i) = index1 i
+   indexv = index1v . (castPtr :: Ptr (Index1 b) -> Ptr b)
+
+instance Storable a => Storable (Index1 a) where
+   sizeOf    ~(Index1 s) = sizeOf s
+   alignment ~(Index1 s) = alignment s
+   peek                  = peek1 Index1 . castPtr
+   poke ptr   (Index1 s) = poke1 (castPtr ptr) s
+
+--------------------------------------------------------------------------------
+
+newtype AttribLocation = AttribLocation GLuint
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+-- | The class of all types which can be used as a generic vertex attribute.
+
+class VertexAttribComponent a where
+   vertexAttrib1 :: AttribLocation -> a -> PrimitiveGL ()
+   vertexAttrib2 :: AttribLocation -> a -> a -> PrimitiveGL ()
+   vertexAttrib3 :: AttribLocation -> a -> a -> a -> PrimitiveGL ()
+   vertexAttrib4 :: AttribLocation -> a -> a -> a -> a -> PrimitiveGL ()
+
+   vertexAttrib1v :: AttribLocation -> Ptr a -> PrimitiveGL ()
+   vertexAttrib2v :: AttribLocation -> Ptr a -> PrimitiveGL ()
+   vertexAttrib3v :: AttribLocation -> Ptr a -> PrimitiveGL ()
+   vertexAttrib4v :: AttribLocation -> Ptr a -> PrimitiveGL ()
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("OpenGL 2.0",glGetVertexAttribdv,GLuint -> GLenum -> Ptr GLdouble -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glGetVertexAttribfv,GLuint -> GLenum -> Ptr GLfloat -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glGetVertexAttribiv,GLuint -> GLenum -> Ptr GLint -> PrimitiveGL ())
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib1s,AttribLocation -> GLshort -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib2s,AttribLocation -> GLshort -> GLshort -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib3s,AttribLocation -> GLshort -> GLshort -> GLshort -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4s,AttribLocation -> GLshort -> GLshort -> GLshort -> GLshort -> PrimitiveGL ())
+
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib1sv,AttribLocation -> Ptr GLshort -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib2sv,AttribLocation -> Ptr GLshort -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib3sv,AttribLocation -> Ptr GLshort -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4sv,AttribLocation -> Ptr GLshort -> PrimitiveGL ())
+
+instance VertexAttribComponent GLshort_ where
+   vertexAttrib1 = glVertexAttrib1s
+   vertexAttrib2 = glVertexAttrib2s
+   vertexAttrib3 = glVertexAttrib3s
+   vertexAttrib4 = glVertexAttrib4s
+
+   vertexAttrib1v = glVertexAttrib1sv
+   vertexAttrib2v = glVertexAttrib2sv
+   vertexAttrib3v = glVertexAttrib3sv
+   vertexAttrib4v = glVertexAttrib4sv
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib1f,AttribLocation -> GLfloat -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib2f,AttribLocation -> GLfloat -> GLfloat -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib3f,AttribLocation -> GLfloat -> GLfloat -> GLfloat -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4f,AttribLocation -> GLfloat -> GLfloat -> GLfloat -> GLfloat -> PrimitiveGL ())
+
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib1fv,AttribLocation -> Ptr GLfloat -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib2fv,AttribLocation -> Ptr GLfloat -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib3fv,AttribLocation -> Ptr GLfloat -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4fv,AttribLocation -> Ptr GLfloat -> PrimitiveGL ())
+
+instance VertexAttribComponent GLfloat_ where
+   vertexAttrib1 = glVertexAttrib1f
+   vertexAttrib2 = glVertexAttrib2f
+   vertexAttrib3 = glVertexAttrib3f
+   vertexAttrib4 = glVertexAttrib4f
+
+   vertexAttrib1v = glVertexAttrib1fv
+   vertexAttrib2v = glVertexAttrib2fv
+   vertexAttrib3v = glVertexAttrib3fv
+   vertexAttrib4v = glVertexAttrib4fv
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib1d,AttribLocation -> GLdouble -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib2d,AttribLocation -> GLdouble -> GLdouble -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib3d,AttribLocation -> GLdouble -> GLdouble -> GLdouble -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4d,AttribLocation -> GLdouble -> GLdouble -> GLdouble -> GLdouble -> PrimitiveGL ())
+
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib1dv,AttribLocation -> Ptr GLdouble -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib2dv,AttribLocation -> Ptr GLdouble -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib3dv,AttribLocation -> Ptr GLdouble -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4dv,AttribLocation -> Ptr GLdouble -> PrimitiveGL ())
+
+instance VertexAttribComponent GLdouble_ where
+   vertexAttrib1 = glVertexAttrib1d
+   vertexAttrib2 = glVertexAttrib2d
+   vertexAttrib3 = glVertexAttrib3d
+   vertexAttrib4 = glVertexAttrib4d
+
+   vertexAttrib1v = glVertexAttrib1dv
+   vertexAttrib2v = glVertexAttrib2dv
+   vertexAttrib3v = glVertexAttrib3dv
+   vertexAttrib4v = glVertexAttrib4dv
+
+--------------------------------------------------------------------------------
+
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4bv,AttribLocation -> Ptr GLbyte -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4ubv,AttribLocation -> Ptr GLubyte -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4usv,AttribLocation -> Ptr GLushort -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4iv,AttribLocation -> Ptr GLint -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4uiv,AttribLocation -> Ptr GLuint -> PrimitiveGL ())
+
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4Nbv,AttribLocation -> Ptr GLbyte -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4Nubv,AttribLocation -> Ptr GLubyte -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4Nusv,AttribLocation -> Ptr GLushort -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4Niv,AttribLocation -> Ptr GLint -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4Nuiv,AttribLocation -> Ptr GLuint -> PrimitiveGL ())
+
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4Nsv,AttribLocation -> Ptr GLshort -> PrimitiveGL ())
+EXTENSION_ENTRY("OpenGL 2.0",glVertexAttrib4Nub,AttribLocation -> GLubyte -> GLubyte -> GLubyte -> GLubyte -> PrimitiveGL ())
+
+--------------------------------------------------------------------------------
+
+class VertexAttrib a where
+   vertexAttrib  :: AttribLocation ->     a -> PrimitiveGL ()
+   vertexAttribv :: AttribLocation -> Ptr a -> PrimitiveGL ()
+
+instance VertexAttribComponent a => VertexAttrib (Vertex2 a) where
+   vertexAttrib location (Vertex2 x y) = vertexAttrib2 location x y
+   vertexAttribv location = vertexAttrib2v location . (castPtr :: Ptr (Vertex2 b) -> Ptr b)
+
+instance VertexAttribComponent a => VertexAttrib (Vertex3 a) where
+   vertexAttrib location (Vertex3 x y z) = vertexAttrib3 location x y z
+   vertexAttribv location = vertexAttrib3v location . (castPtr :: Ptr (Vertex3 b) -> Ptr b)
+
+instance VertexAttribComponent a => VertexAttrib (Vertex4 a) where
+   vertexAttrib location (Vertex4 x y z w) = vertexAttrib4 location x y z w
+   vertexAttribv location = vertexAttrib4v location . (castPtr :: Ptr (Vertex4 b) -> Ptr b)
+
+instance VertexAttribComponent a => VertexAttrib (TexCoord1 a) where
+   vertexAttrib location (TexCoord1 s) = vertexAttrib1 location s
+   vertexAttribv location = vertexAttrib1v location . (castPtr :: Ptr (TexCoord1 b) -> Ptr b)
+
+instance VertexAttribComponent a => VertexAttrib (TexCoord2 a) where
+   vertexAttrib location (TexCoord2 s t) = vertexAttrib2 location s t
+   vertexAttribv location = vertexAttrib2v location . (castPtr :: Ptr (TexCoord2 b) -> Ptr b)
+
+instance VertexAttribComponent a => VertexAttrib (TexCoord3 a) where
+   vertexAttrib location (TexCoord3 s t u) = vertexAttrib3 location s t u
+   vertexAttribv location = vertexAttrib3v location . (castPtr :: Ptr (TexCoord3 b) -> Ptr b)
+
+instance VertexAttribComponent a => VertexAttrib (TexCoord4 a) where
+   vertexAttrib location (TexCoord4 s t u v) = vertexAttrib4 location s t u v
+   vertexAttribv location = vertexAttrib4v location . (castPtr :: Ptr (TexCoord4 b) -> Ptr b)
+
+instance VertexAttribComponent a => VertexAttrib (Normal3 a) where
+   vertexAttrib location (Normal3 x y z) = vertexAttrib3 location x y z
+   vertexAttribv location = vertexAttrib3v location . (castPtr :: Ptr (Normal3 b) -> Ptr b)
+
+instance VertexAttribComponent a => VertexAttrib (FogCoord1 a) where
+   vertexAttrib location (FogCoord1 c) = vertexAttrib1 location c
+   vertexAttribv location = vertexAttrib1v location . (castPtr :: Ptr (FogCoord1 b) -> Ptr b)
+
+instance VertexAttribComponent a => VertexAttrib (Color3 a) where
+   vertexAttrib location (Color3 r g b) = vertexAttrib3 location r g b
+   vertexAttribv location = vertexAttrib3v location . (castPtr :: Ptr (Color3 b) -> Ptr b)
+
+instance VertexAttribComponent a => VertexAttrib (Color4 a) where
+   vertexAttrib location (Color4 r g b a) = vertexAttrib4 location r g b a
+   vertexAttribv location = vertexAttrib4v location . (castPtr :: Ptr (Color4 b) -> Ptr b)
+
+instance VertexAttribComponent a => VertexAttrib (Index1 a) where
+   vertexAttrib location (Index1 i) = vertexAttrib1 location i
+   vertexAttribv location = vertexAttrib1v location . (castPtr :: Ptr (Index1 b) -> Ptr b)
+
+--------------------------------------------------------------------------------
+
+-- | An implementation must support at least 2 texture units, but it may
+-- support up to 32 ones. This state variable can be used to query the actual
+-- implementation limit.
+
+maxTextureUnit :: GettableStateVar TextureUnit
+maxTextureUnit =
+   makeGettableStateVar (getEnum1 unmarshalTextureUnit GetMaxTextureUnits)
diff --git a/Graphics/Rendering/OGL/GLU.hs b/Graphics/Rendering/OGL/GLU.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GLU.hs
@@ -0,0 +1,31 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GLU
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- A Haskell binding for GLU, OpenGL\'s accompanying utility library.
+--
+-----------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GLU (
+     module Graphics.Rendering.OGL.GLU.Initialization,
+     module Graphics.Rendering.OGL.GLU.Mipmapping,
+     module Graphics.Rendering.OGL.GLU.Matrix,
+     module Graphics.Rendering.OGL.GLU.Tessellation,
+     module Graphics.Rendering.OGL.GLU.Quadrics,
+     module Graphics.Rendering.OGL.GLU.NURBS,
+     module Graphics.Rendering.OGL.GLU.Errors
+) where
+
+import Graphics.Rendering.OGL.GLU.Initialization
+import Graphics.Rendering.OGL.GLU.Mipmapping
+import Graphics.Rendering.OGL.GLU.Matrix
+import Graphics.Rendering.OGL.GLU.Tessellation
+import Graphics.Rendering.OGL.GLU.Quadrics
+import Graphics.Rendering.OGL.GLU.NURBS
+import Graphics.Rendering.OGL.GLU.Errors
diff --git a/Graphics/Rendering/OGL/GLU/Errors.hs b/Graphics/Rendering/OGL/GLU/Errors.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GLU/Errors.hs
@@ -0,0 +1,36 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GLU.Errors
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to section 2.5 (GL Errors) of the OpenGL 2.1 specs
+-- and chapter 8 (Errors) of the GLU specs, offering a generalized view of
+-- errors in GL and GLU.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GLU.Errors (
+   Error(..), ErrorCategory(..), errors
+) where
+
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal (
+   Error(..), ErrorCategory(..), getErrors )
+
+--------------------------------------------------------------------------------
+
+-- | When an error occurs, it is recorded in this state variable and no further
+-- errors are recorded. Reading 'errors' returns the currently recorded errors
+-- (there may be more than one due to a possibly distributed implementation) and
+-- resets the state variable to @[]@, re-enabling the recording of future
+-- errors. The value @[]@ means that there has been no detectable error since
+-- the last time 'errors' was read, or since the GL was initialized.
+
+errors :: GettableStateVar [Error]
+errors = makeGettableStateVar getErrors
diff --git a/Graphics/Rendering/OGL/GLU/ErrorsInternal.hs b/Graphics/Rendering/OGL/GLU/ErrorsInternal.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GLU/ErrorsInternal.hs
@@ -0,0 +1,249 @@
+{-# OPTIONS_GHC -fno-cse #-}
+
+-- #hide
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GLU.ErrorsInternal
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This is a purely internal module corresponding to some parts of section 2.5
+-- (GL Errors) of the OpenGL 2.1 specs and chapter 8 (Errors) of the GLU specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GLU.ErrorsInternal (
+   Error(..), ErrorCategory(..), getErrors,
+   recordErrorCode, recordInvalidEnum, recordInvalidValue, recordOutOfMemory
+) where
+
+import Foreign.Ptr ( Ptr, castPtr )
+import Foreign.C.String ( peekCString )
+import Data.IORef ( IORef, newIORef, readIORef, writeIORef )
+import System.IO.Unsafe ( unsafePerformIO )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum, GLubyte )
+
+--------------------------------------------------------------------------------
+-- Alas, GL and GLU define error enumerants with the same names, so we have to
+-- rename these to avoid name clashes. Ugly, ugly, ugly...
+
+data GL_ErrorCode =
+     GL_NoError
+   | GL_InvalidEnum
+   | GL_InvalidValue
+   | GL_InvalidOperation
+   | GL_StackOverflow
+   | GL_StackUnderflow
+   | GL_OutOfMemory
+   | GL_TableTooLarge
+
+gl_marshalErrorCode :: GL_ErrorCode -> GLenum
+gl_marshalErrorCode x = case x of
+   GL_NoError -> 0x0
+   GL_InvalidEnum -> 0x500
+   GL_InvalidValue -> 0x501
+   GL_InvalidOperation -> 0x502
+   GL_StackOverflow -> 0x503
+   GL_StackUnderflow -> 0x504
+   GL_OutOfMemory -> 0x505
+   GL_TableTooLarge -> 0x8031
+
+--------------------------------------------------------------------------------
+-- See comment above
+
+data GLU_ErrorCode =
+     GLU_InvalidEnum
+   | GLU_InvalidValue
+   | GLU_OutOfMemory
+   | GLU_InvalidOperation
+
+glu_marshalErrorCode :: GLU_ErrorCode -> GLenum
+glu_marshalErrorCode x = case x of
+   GLU_InvalidEnum -> 0x18a24
+   GLU_InvalidValue -> 0x18a25
+   GLU_OutOfMemory -> 0x18a26
+   GLU_InvalidOperation -> 0x18a28
+
+--------------------------------------------------------------------------------
+
+-- only the errors with the smallest and the largsest enum value
+data NurbsError =
+     NurbsError1
+   | NurbsError37
+
+marshalNurbsError :: NurbsError -> GLenum
+marshalNurbsError x = case x of
+   NurbsError1 -> 0x1879b
+   NurbsError37 -> 0x187bf
+
+--------------------------------------------------------------------------------
+
+-- only the errors with the smallest and the largsest enum value
+data TessError =
+     TessError1
+   | TessError8
+
+marshalTessError :: TessError -> GLenum
+marshalTessError x = case x of
+   TessError1 -> 0x18737
+   TessError8 -> 0x1873e
+
+--------------------------------------------------------------------------------
+
+-- | GL\/GLU errors consist of a general error category and a description of
+-- what went wrong.
+
+data Error = Error ErrorCategory String
+   deriving ( Eq, Ord, Show )
+
+--------------------------------------------------------------------------------
+
+-- | General GL\/GLU error categories
+
+data ErrorCategory
+   = InvalidEnum
+   | InvalidValue
+   | InvalidOperation
+   | StackOverflow
+   | StackUnderflow
+   | OutOfMemory
+   | TableTooLarge
+   | TesselatorError
+   | NURBSError
+   deriving ( Eq, Ord, Show )
+
+unmarshalErrorCategory :: GLenum -> ErrorCategory
+unmarshalErrorCategory c
+   | isInvalidEnum c      = InvalidEnum
+   | isInvalidValue c     = InvalidValue
+   | isOutOfMemory c      = OutOfMemory
+   | isInvalidOperation c = InvalidOperation
+   | isStackOverflow c    = StackOverflow
+   | isStackUnderflow c   = StackUnderflow
+   | isTableTooLarge c    = TableTooLarge
+   | isTesselatorError c  = TesselatorError
+   | isNURBSError c       = NURBSError
+   | otherwise = error "unmarshalErrorCategory"
+
+isInvalidEnum :: GLenum -> Bool
+isInvalidEnum c =
+   c == gl_marshalErrorCode  GL_InvalidEnum ||
+   c == glu_marshalErrorCode GLU_InvalidEnum
+
+isInvalidValue :: GLenum -> Bool
+isInvalidValue c =
+   c == gl_marshalErrorCode  GL_InvalidValue ||
+   c == glu_marshalErrorCode GLU_InvalidValue
+
+isOutOfMemory :: GLenum -> Bool
+isOutOfMemory c =
+   c == gl_marshalErrorCode  GL_OutOfMemory ||
+   c == glu_marshalErrorCode GLU_OutOfMemory
+
+isInvalidOperation :: GLenum -> Bool
+isInvalidOperation c =
+   c == gl_marshalErrorCode  GL_InvalidOperation ||
+   c == glu_marshalErrorCode GLU_InvalidOperation
+
+isStackOverflow :: GLenum -> Bool
+isStackOverflow c =
+   c == gl_marshalErrorCode GL_StackOverflow
+
+isStackUnderflow :: GLenum -> Bool
+isStackUnderflow c =
+   c == gl_marshalErrorCode GL_StackUnderflow
+
+isTableTooLarge :: GLenum -> Bool
+isTableTooLarge c =
+   c == gl_marshalErrorCode GL_TableTooLarge
+
+isTesselatorError :: GLenum -> Bool
+isTesselatorError c =
+   marshalTessError TessError1 <= c &&
+   c <= marshalTessError TessError8
+
+isNURBSError :: GLenum -> Bool
+isNURBSError c =
+   marshalNurbsError NurbsError1 <= c &&
+   c <= marshalNurbsError NurbsError37
+
+--------------------------------------------------------------------------------
+
+-- The returned error string is statically allocated, so peekCString
+-- does the right thing here. No malloc/free necessary here.
+
+makeError :: GLenum -> IO Error
+makeError e = do
+   let category = unmarshalErrorCategory e
+   ptr <- gluErrorString e
+   description <- peekCString (castPtr ptr)
+   return $ Error category description
+
+foreign import CALLCONV unsafe "gluErrorString" gluErrorString ::
+   GLenum -> IO (Ptr GLubyte)
+
+--------------------------------------------------------------------------------
+
+-- This seems to be a common Haskell hack nowadays: A plain old global variable
+-- with an associated getter and mutator. Perhaps some language/library support
+-- is needed?
+
+{-# NOINLINE theRecordedErrors #-}
+theRecordedErrors :: IORef ([GLenum],Bool)
+theRecordedErrors = unsafePerformIO (newIORef ([], True))
+
+getRecordedErrors :: IO ([GLenum],Bool)
+getRecordedErrors =  readIORef theRecordedErrors
+
+setRecordedErrors :: ([GLenum],Bool) -> IO ()
+setRecordedErrors = writeIORef theRecordedErrors
+
+--------------------------------------------------------------------------------
+
+getGLErrors :: IO [GLenum]
+getGLErrors = getGLErrorsAux []
+   where getGLErrorsAux acc = do
+            errorCode <- glGetError
+            if isError errorCode
+               then getGLErrorsAux (errorCode : acc)
+               else return $ reverse acc
+
+isError :: GLenum -> Bool
+isError = (/= gl_marshalErrorCode GL_NoError)
+
+foreign import CALLCONV unsafe "glGetError" glGetError :: IO GLenum
+
+--------------------------------------------------------------------------------
+
+getErrors :: IO [Error]
+getErrors = do
+   es <- getErrorCodesAux (const ([], True))
+   mapM makeError es
+
+recordErrorCode :: GLenum -> IO ()
+recordErrorCode e = do
+   getErrorCodesAux (\es -> (if null es then [e] else [], False))
+   return ()
+
+recordInvalidEnum :: IO ()
+recordInvalidEnum = recordErrorCode (gl_marshalErrorCode GL_InvalidEnum)
+
+recordInvalidValue :: IO ()
+recordInvalidValue = recordErrorCode (gl_marshalErrorCode GL_InvalidValue)
+
+recordOutOfMemory :: IO ()
+recordOutOfMemory = recordErrorCode (glu_marshalErrorCode GLU_OutOfMemory)
+
+-- ToDo: Make this thread-safe
+getErrorCodesAux :: ([GLenum] -> ([GLenum],Bool)) -> IO [GLenum]
+getErrorCodesAux f = do
+   (recordedErrors, useGLErrors) <- getRecordedErrors
+   glErrors <- getGLErrors
+   let es = if useGLErrors then recordedErrors ++ glErrors else recordedErrors
+   setRecordedErrors (f es)
+   return es
diff --git a/Graphics/Rendering/OGL/GLU/Initialization.hs b/Graphics/Rendering/OGL/GLU/Initialization.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GLU/Initialization.hs
@@ -0,0 +1,56 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GLU.Initialization
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to chapter 2 (Initialization) of the GLU specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GLU.Initialization (
+   gluVersion, gluExtensions
+) where
+
+import Foreign.Ptr ( Ptr, nullPtr, castPtr )
+import Foreign.C.String ( peekCString )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum, GLubyte )
+import Graphics.Rendering.OGL.GL.StateVar (
+   GettableStateVar, makeGettableStateVar )
+
+--------------------------------------------------------------------------------
+
+gluVersion :: GettableStateVar String
+gluVersion = makeGettableStateVar (getString Version)
+
+gluExtensions :: GettableStateVar [String]
+gluExtensions = makeGettableStateVar (fmap words $ getString Extensions)
+
+--------------------------------------------------------------------------------
+
+data StringName =
+     Version
+   | Extensions
+   deriving ( Eq, Ord, Show )
+
+marshalStringName :: StringName -> GLenum
+marshalStringName x = case x of
+   Version -> 0x189c0
+   Extensions -> 0x189c1
+
+--------------------------------------------------------------------------------
+
+getString :: StringName -> IO String
+getString n = do
+   ptr <- gluGetString (marshalStringName n)
+   if ptr == nullPtr
+      then return ""
+      else peekCString (castPtr ptr)
+
+foreign import CALLCONV unsafe "gluGetString" gluGetString ::
+   GLenum -> IO (Ptr GLubyte)
diff --git a/Graphics/Rendering/OGL/GLU/Matrix.hs b/Graphics/Rendering/OGL/GLU/Matrix.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GLU/Matrix.hs
@@ -0,0 +1,162 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GLU.Matrix
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to chapter 4 (Matrix Manipulation) of the GLU specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GLU.Matrix (
+   ortho2D, perspective, lookAt, pickMatrix,
+   project, unProject, unProject4
+) where
+
+import Foreign.Marshal.Alloc ( alloca )
+import Foreign.Marshal.Array ( withArray )
+import Foreign.Ptr ( Ptr )
+import Foreign.Storable ( Storable(peek,peekElemOff) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLint, GLdouble, GLclampd )
+import Graphics.Rendering.OGL.GL.CoordTrans (
+   MatrixOrder(..), Matrix(..), MatrixComponent,
+   Vector3(..), Position(..), Size(..) )
+import Graphics.Rendering.OGL.GL.Extensions (
+   FunPtr, unsafePerformIO, Invoker, getProcAddress )
+import Graphics.Rendering.OGL.GL.GLboolean ( unmarshalGLboolean )
+import Graphics.Rendering.OGL.GL.VertexSpec ( Vertex3(..), Vertex4(..) )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal ( recordInvalidValue )
+
+--------------------------------------------------------------------------------
+
+#include "HsOpenGLExt.h"
+
+--------------------------------------------------------------------------------
+-- matrix setup
+
+foreign import CALLCONV unsafe "gluOrtho2D" ortho2D ::
+   GLdouble -> GLdouble -> GLdouble -> GLdouble -> GL ()
+
+foreign import CALLCONV unsafe "gluPerspective" perspective ::
+   GLdouble -> GLdouble -> GLdouble -> GLdouble -> GL ()
+
+lookAt :: Vertex3 GLdouble -> Vertex3 GLdouble -> Vector3 GLdouble -> GL ()
+lookAt (Vertex3 eyeX    eyeY    eyeZ)
+       (Vertex3 centerX centerY centerZ)
+       (Vector3 upX     upY     upZ) =
+   gluLookAt eyeX eyeY eyeZ centerX centerY centerZ upX upY upZ
+
+foreign import CALLCONV unsafe "gluLookAt" gluLookAt ::
+      GLdouble -> GLdouble -> GLdouble
+   -> GLdouble -> GLdouble -> GLdouble
+   -> GLdouble -> GLdouble -> GLdouble -> GL ()
+
+pickMatrix ::
+   (GLdouble, GLdouble) -> (GLdouble, GLdouble) -> (Position, Size) -> GL ()
+pickMatrix (x, y) (w, h) viewport = liftIO .
+   withViewport viewport $ gluPickMatrix x y w h
+
+foreign import CALLCONV unsafe "gluPickMatrix" gluPickMatrix ::
+   GLdouble -> GLdouble -> GLdouble -> GLdouble -> Ptr GLint -> IO ()
+
+--------------------------------------------------------------------------------
+-- coordinate projection
+
+project ::
+      Matrix m
+   => Vertex3 GLdouble -> m GLdouble -> m GLdouble -> (Position, Size)
+   -> GL (Vertex3 GLdouble)
+project (Vertex3 objX objY objZ) model proj viewport = liftIO . 
+   withColumnMajor model $ \modelBuf ->
+   withColumnMajor proj $ \projBuf ->
+   withViewport viewport $ \viewBuf ->
+   getVertex3 $ gluProject objX objY objZ modelBuf projBuf viewBuf
+
+foreign import CALLCONV unsafe "gluProject" gluProject ::
+      GLdouble -> GLdouble -> GLdouble
+   -> Ptr GLdouble -> Ptr GLdouble -> Ptr GLint
+   -> Ptr GLdouble -> Ptr GLdouble -> Ptr GLdouble -> IO GLint
+
+unProject ::
+      Matrix m
+   => Vertex3 GLdouble -> m GLdouble -> m GLdouble -> (Position, Size)
+   -> GL (Vertex3 GLdouble)
+unProject (Vertex3 objX objY objZ) model proj viewport = liftIO .
+   withColumnMajor model $ \modelBuf ->
+   withColumnMajor proj $ \projBuf ->
+   withViewport viewport $ \viewBuf ->
+   getVertex3 $ gluUnProject objX objY objZ modelBuf projBuf viewBuf
+
+foreign import CALLCONV unsafe "gluUnProject" gluUnProject ::
+      GLdouble -> GLdouble -> GLdouble
+   -> Ptr GLdouble -> Ptr GLdouble -> Ptr GLint
+   -> Ptr GLdouble -> Ptr GLdouble -> Ptr GLdouble -> IO GLint
+
+unProject4 ::
+      Matrix m
+   => Vertex4 GLdouble -> m GLdouble -> m GLdouble -> (Position, Size)
+   -> GLclampd -> GLclampd
+   -> GL (Vertex4 GLdouble)
+unProject4 (Vertex4 objX objY objZ clipW) model proj viewport near far = liftIO .
+   withColumnMajor model $ \modelBuf ->
+   withColumnMajor proj $ \projBuf ->
+   withViewport viewport $ \viewBuf ->
+   getVertex4 $
+      gluUnProject4 objX objY objZ clipW modelBuf projBuf viewBuf near far
+
+EXTENSION_ENTRY("GLU 1.3",gluUnProject4,GLdouble -> GLdouble -> GLdouble -> GLdouble -> Ptr GLdouble -> Ptr GLdouble -> Ptr GLint -> GLclampd -> GLclampd -> Ptr GLdouble -> Ptr GLdouble -> Ptr GLdouble -> Ptr GLdouble -> IO GLint)
+
+--------------------------------------------------------------------------------
+
+withViewport :: (Position, Size) -> (Ptr GLint -> IO a ) -> IO a
+withViewport (Position x y, Size w h) =
+   withArray [ x, y, fromIntegral w, fromIntegral h ]
+
+withColumnMajor :: (Matrix m, MatrixComponent c) => m c -> (Ptr c -> IO b) -> IO b
+withColumnMajor mat act = runGL $ withMatrix mat (\x y -> liftIO $ juggle x y)
+   where juggle ColumnMajor p = act p
+         juggle RowMajor    p = do
+            transposedElems <- mapM (peekElemOff p) [ 0, 4,  8, 12,
+                                                      1, 5,  9, 13,
+                                                      2, 6, 10, 14,
+                                                      3, 7, 11, 15 ]
+            withArray transposedElems act
+
+getVertex3 ::
+      (Ptr GLdouble -> Ptr GLdouble -> Ptr GLdouble -> IO GLint)
+   -> IO (Vertex3 GLdouble)
+getVertex3 act =
+   alloca $ \xBuf ->
+   alloca $ \yBuf ->
+   alloca $ \zBuf -> do
+   ok <- act xBuf yBuf zBuf
+   if unmarshalGLboolean ok
+      then do x <- peek xBuf
+              y <- peek yBuf
+              z <- peek zBuf
+              return $ Vertex3 x y z
+      else do recordInvalidValue
+              return $ Vertex3 0 0 0
+
+getVertex4 ::
+      (Ptr GLdouble -> Ptr GLdouble -> Ptr GLdouble -> Ptr GLdouble -> IO GLint)
+   -> IO (Vertex4 GLdouble)
+getVertex4 act =
+   alloca $ \xBuf ->
+   alloca $ \yBuf ->
+   alloca $ \zBuf ->
+   alloca $ \wBuf -> do
+   ok <- act xBuf yBuf zBuf wBuf
+   if unmarshalGLboolean ok
+      then do x <- peek xBuf
+              y <- peek yBuf
+              z <- peek zBuf
+              w <- peek wBuf
+              return $ Vertex4 x y z w
+      else do recordInvalidValue
+              return $ Vertex4 0 0 0 0
diff --git a/Graphics/Rendering/OGL/GLU/Mipmapping.hs b/Graphics/Rendering/OGL/GLU/Mipmapping.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GLU/Mipmapping.hs
@@ -0,0 +1,76 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GLU.Mipmapping
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to chapter 3 (Mipmapping) of the GLU specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GLU.Mipmapping (
+   scaleImage, build1DMipmaps, build2DMipmaps
+) where
+
+import Foreign.Ptr ( Ptr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes ( GLsizei, GLint, GLenum )
+import Graphics.Rendering.OGL.GL.CoordTrans ( Size(..) )
+import Graphics.Rendering.OGL.GL.PixelData ( PixelData, withPixelData )
+import Graphics.Rendering.OGL.GL.Texturing.PixelInternalFormat (
+   PixelInternalFormat, marshalPixelInternalFormat )
+import Graphics.Rendering.OGL.GL.Texturing.TextureTarget (
+   TextureTarget, marshalTextureTarget )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal ( recordInvalidValue )
+
+--------------------------------------------------------------------------------
+-- Section 3.1 (Image Scaling)
+
+scaleImage :: Size -> PixelData a -> Size -> PixelData b -> GL ()
+scaleImage (Size widthIn  heightIn)  pdIn (Size widthOut heightOut) pdOut = liftIO .
+   withPixelData pdIn $ \fIn dIn pIn ->
+      withPixelData pdOut $ \fOut dOut pOut ->
+         if fIn == fOut
+            then gluScaleImage
+                    fIn widthIn heightIn dIn pIn widthOut heightOut dOut pOut
+            else recordInvalidValue
+
+foreign import CALLCONV unsafe "gluScaleImage" gluScaleImage ::
+   GLenum -> GLsizei -> GLsizei -> GLenum -> Ptr a
+          -> GLsizei -> GLsizei -> GLenum -> Ptr b -> IO ()
+
+--------------------------------------------------------------------------------
+-- Section 3.2 (Automatic Mipmapping)
+-- Missing for GLU 1.3: gluBuild3DMipmaps, gluBuild{1,2,3}DMipmapLevels
+
+build1DMipmaps ::
+   TextureTarget -> PixelInternalFormat -> GLsizei -> PixelData a -> GL ()
+build1DMipmaps target internalFormat height pd = liftIO $ do
+   withPixelData pd $
+      gluBuild1DMipmaps
+         (marshalTextureTarget target)
+         (marshalPixelInternalFormat internalFormat)
+         height
+   return ()   -- TODO: Should we use the return value?
+
+foreign import CALLCONV unsafe "gluBuild1DMipmaps" gluBuild1DMipmaps ::
+      GLenum -> GLint -> GLsizei -> GLenum -> GLenum -> Ptr a -> IO GLint
+
+--------------------------------------------------------------------------------
+
+build2DMipmaps :: TextureTarget -> PixelInternalFormat -> GLsizei -> GLsizei
+               -> PixelData a -> GL ()
+build2DMipmaps target internalFormat width height pd = liftIO $ do
+   withPixelData pd $
+      gluBuild2DMipmaps
+         (marshalTextureTarget target)
+         (marshalPixelInternalFormat internalFormat)
+         width height
+   return ()   -- TODO: Should we use the return value?
+
+foreign import CALLCONV unsafe "gluBuild2DMipmaps" gluBuild2DMipmaps ::
+      GLenum -> GLint -> GLsizei -> GLsizei -> GLenum -> GLenum -> Ptr a -> IO GLint
diff --git a/Graphics/Rendering/OGL/GLU/NURBS.hs b/Graphics/Rendering/OGL/GLU/NURBS.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GLU/NURBS.hs
@@ -0,0 +1,466 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GLU.NURBS
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to chapter 7 (NURBS) of the GLU specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GLU.NURBS (
+   NURBSObj, withNURBSObj,
+   NURBSBeginCallback, withNURBSBeginCallback,
+   NURBSVertexCallback, withNURBSVertexCallback,
+   NURBSNormalCallback, withNURBSNormalCallback,
+   NURBSColorCallback, withNURBSColorCallback,
+   NURBSEndCallback, withNURBSEndCallback,
+   checkForNURBSError,
+   nurbsBeginEndCurve, nurbsCurve,
+   nurbsBeginEndSurface, nurbsSurface,
+   TrimmingPoint, nurbsBeginEndTrim, pwlCurve, trimmingCurve,
+   NURBSMode(..), setNURBSMode,
+   setNURBSCulling,
+   SamplingMethod(..), setSamplingMethod,
+   loadSamplingMatrices,
+   DisplayMode'(..), setDisplayMode'
+) where
+
+import Control.Monad ( unless )
+import Foreign.Marshal.Array ( withArray )
+import Foreign.Ptr ( Ptr, nullPtr, castPtr, FunPtr, freeHaskellFunPtr )
+import Foreign.Storable ( Storable(..) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLenum, GLint, GLfloat, Capability )
+import Graphics.Rendering.OGL.GL.Capability ( marshalCapability )
+import Graphics.Rendering.OGL.GL.ControlPoint
+import Graphics.Rendering.OGL.GL.CoordTrans (
+   Position(..), Size(..), MatrixOrder(ColumnMajor), MatrixComponent, Matrix(..) )
+import Graphics.Rendering.OGL.GL.Exception ( bracket, bracket_ )
+import Graphics.Rendering.OGL.GL.GLboolean ( marshalGLboolean )
+import Graphics.Rendering.OGL.GL.PrimitiveMode ( unmarshalPrimitiveMode )
+import Graphics.Rendering.OGL.GL.BeginEnd ( PrimitiveMode )
+import Graphics.Rendering.OGL.GL.VertexSpec (
+   Vertex2, Vertex3, Normal3, Color4 )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal (
+   recordErrorCode, recordOutOfMemory )
+
+--------------------------------------------------------------------------------
+
+data NURBSCallback =
+     Error
+   | Begin
+   | Vertex
+   | Normal
+   | Color
+   | TextureCoord
+   | End
+   | BeginData
+   | VertexData
+   | NormalData
+   | ColorData
+   | TextureCoordData
+   | EndData
+
+marshalNURBSCallback :: NURBSCallback -> GLenum
+marshalNURBSCallback x = case x of
+   Error -> 100103
+   Begin -> 100164
+   Vertex -> 100165
+   Normal -> 100166
+   Color -> 100167
+   TextureCoord -> 100168
+   End -> 100169
+   BeginData -> 100170
+   VertexData -> 100171
+   NormalData -> 100172
+   ColorData -> 100173
+   TextureCoordData -> 100174
+   EndData -> 100175
+
+--------------------------------------------------------------------------------
+-- chapter 7.1: The NURBS Object
+
+-- an opaque pointer to a NURBS object
+newtype NURBSObj = NURBSObj (Ptr NURBSObj)
+
+isNullNURBSObj :: NURBSObj -> Bool
+isNullNURBSObj (NURBSObj ptr) = ptr == nullPtr
+
+withNURBSObj :: a -> (NURBSObj -> GL a) -> GL a
+withNURBSObj failureValue action = liftIO $ 
+   bracket gluNewNurbsRenderer safeDeleteNurbsRenderer
+           (\nurbsObj -> if isNullNURBSObj nurbsObj
+                            then do recordOutOfMemory
+                                    return failureValue
+                            else (runGL $ action nurbsObj))
+
+foreign import CALLCONV safe "gluNewNurbsRenderer"
+   gluNewNurbsRenderer :: IO NURBSObj
+
+safeDeleteNurbsRenderer :: NURBSObj -> IO ()
+safeDeleteNurbsRenderer nurbsObj =
+   unless (isNullNURBSObj nurbsObj) $ gluDeleteNurbsRenderer nurbsObj
+
+foreign import CALLCONV safe "gluDeleteNurbsRenderer"
+   gluDeleteNurbsRenderer :: NURBSObj -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 7.2: Callbacks (begin)
+
+type NURBSBeginCallback = PrimitiveMode -> GL ()
+
+type BeginCallback' = GLenum -> GL ()
+
+withNURBSBeginCallback :: NURBSObj -> NURBSBeginCallback -> GL a -> GL a
+withNURBSBeginCallback nurbsObj beginCallback action = liftIO $
+   bracket (makeBeginCallback (beginCallback . unmarshalPrimitiveMode))
+           freeHaskellFunPtr $ \callbackPtr -> do
+      setBeginCallback nurbsObj (marshalNURBSCallback Begin) callbackPtr
+      (runGL action)
+
+foreign import CALLCONV "wrapper" makeBeginCallback ::
+   BeginCallback' -> IO (FunPtr BeginCallback')
+
+foreign import CALLCONV safe "gluNurbsCallback"
+   setBeginCallback :: NURBSObj -> GLenum -> FunPtr BeginCallback' -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 7.2: Callbacks (vertex)
+
+type NURBSVertexCallback = Vertex3 GLfloat -> GL ()
+
+type VertexCallback' = Ptr (Vertex3 GLfloat) -> GL ()
+
+withNURBSVertexCallback :: NURBSObj -> NURBSVertexCallback -> GL a -> GL a
+withNURBSVertexCallback nurbsObj vertexCallback action = liftIO $
+   bracket (makeVertexCallback (\p -> liftIO (peek p) >>= vertexCallback))
+           freeHaskellFunPtr $ \callbackPtr -> do
+      setVertexCallback nurbsObj (marshalNURBSCallback Vertex) callbackPtr
+      (runGL action)
+
+foreign import CALLCONV "wrapper" makeVertexCallback ::
+   VertexCallback' -> IO (FunPtr VertexCallback')
+
+foreign import CALLCONV safe "gluNurbsCallback"
+   setVertexCallback :: NURBSObj -> GLenum -> FunPtr VertexCallback' -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 7.2: Callbacks (normal)
+
+type NURBSNormalCallback = Normal3 GLfloat -> GL ()
+
+type NormalCallback' = Ptr (Normal3 GLfloat) -> GL ()
+
+withNURBSNormalCallback :: NURBSObj -> NURBSNormalCallback -> GL a -> GL a
+withNURBSNormalCallback nurbsObj normalCallback action = liftIO $
+   bracket (makeNormalCallback (\p -> liftIO (peek p) >>= normalCallback))
+           freeHaskellFunPtr $ \callbackPtr -> do
+      setNormalCallback nurbsObj (marshalNURBSCallback Normal) callbackPtr
+      (runGL action)
+
+foreign import CALLCONV "wrapper" makeNormalCallback ::
+   NormalCallback' -> IO (FunPtr NormalCallback')
+
+foreign import CALLCONV safe "gluNurbsCallback"
+   setNormalCallback :: NURBSObj -> GLenum -> FunPtr NormalCallback' -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 7.2: Callbacks (color)
+
+type NURBSColorCallback = Color4 GLfloat -> GL ()
+
+type ColorCallback' = Ptr (Color4 GLfloat) -> GL ()
+
+withNURBSColorCallback :: NURBSObj -> NURBSColorCallback -> GL a -> GL a
+withNURBSColorCallback nurbsObj colorCallback action = liftIO $
+   bracket (makeColorCallback (\p -> liftIO (peek p) >>= colorCallback))
+           freeHaskellFunPtr $ \callbackPtr -> do
+      setColorCallback nurbsObj (marshalNURBSCallback Color) callbackPtr
+      (runGL action)
+
+foreign import CALLCONV "wrapper" makeColorCallback ::
+   ColorCallback' -> IO (FunPtr ColorCallback')
+
+foreign import CALLCONV safe "gluNurbsCallback"
+   setColorCallback :: NURBSObj -> GLenum -> FunPtr ColorCallback' -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 7.2: Callbacks (end)
+
+type NURBSEndCallback = GL ()
+
+withNURBSEndCallback :: NURBSObj -> NURBSEndCallback -> GL a -> GL a
+withNURBSEndCallback nurbsObj endCallback action = liftIO $
+   bracket (makeEndCallback endCallback)
+           freeHaskellFunPtr $ \callbackPtr -> do
+      setEndCallback nurbsObj (marshalNURBSCallback End) callbackPtr
+      (runGL action)
+
+foreign import CALLCONV "wrapper" makeEndCallback ::
+   NURBSEndCallback -> IO (FunPtr NURBSEndCallback)
+
+foreign import CALLCONV safe "gluNurbsCallback"
+   setEndCallback :: NURBSObj -> GLenum -> FunPtr NURBSEndCallback -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 7.2: Callbacks (error)
+
+type ErrorCallback = GLenum -> GL ()
+
+withErrorCallback :: NURBSObj -> ErrorCallback -> GL a -> GL a
+withErrorCallback nurbsObj errorCallback action = liftIO $ 
+   bracket (makeErrorCallback errorCallback)
+           freeHaskellFunPtr $ \callbackPtr -> do
+      setErrorCallback nurbsObj (marshalNURBSCallback Error) callbackPtr
+      (runGL action)
+
+foreign import CALLCONV "wrapper" makeErrorCallback ::
+   ErrorCallback -> IO (FunPtr ErrorCallback)
+
+foreign import CALLCONV safe "gluNurbsCallback"
+   setErrorCallback :: NURBSObj -> GLenum -> FunPtr ErrorCallback -> IO ()
+
+checkForNURBSError :: NURBSObj -> GL a -> GL a
+checkForNURBSError nurbsObj = withErrorCallback nurbsObj (liftIO . recordErrorCode)
+
+--------------------------------------------------------------------------------
+-- chapter 7.3: NURBS Curves
+
+nurbsBeginEndCurve :: NURBSObj -> GL a -> GL a
+nurbsBeginEndCurve nurbsObj x = liftIO $
+   bracket_ (gluBeginCurve nurbsObj) (gluEndCurve nurbsObj) (runGL x)
+
+foreign import CALLCONV safe "gluBeginCurve"
+   gluBeginCurve :: NURBSObj -> IO ()
+
+nurbsCurve :: ControlPoint c => NURBSObj -> GLint -> Ptr GLfloat -> GLint -> Ptr (c GLfloat) -> GLint -> GL ()
+nurbsCurve nurbsObj knotCount knots stride control order =
+   gluNurbsCurve nurbsObj knotCount knots stride (castPtr control) order (map1Target (pseudoPeek control))
+
+pseudoPeek :: Ptr (c GLfloat) -> c GLfloat
+pseudoPeek _ = undefined
+
+foreign import CALLCONV safe "gluNurbsCurve"
+   gluNurbsCurve :: NURBSObj -> GLint -> Ptr GLfloat -> GLint -> Ptr GLfloat -> GLint -> GLenum -> GL ()
+
+foreign import CALLCONV safe "gluEndCurve"
+   gluEndCurve :: NURBSObj -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 7.4: NURBS Surfaces
+
+nurbsBeginEndSurface :: NURBSObj -> GL a -> GL a
+nurbsBeginEndSurface nurbsObj x = liftIO $
+   bracket_ (gluBeginSurface nurbsObj) (gluEndSurface nurbsObj) (runGL x)
+
+foreign import CALLCONV safe "gluBeginSurface"
+   gluBeginSurface :: NURBSObj -> IO ()
+
+nurbsSurface :: ControlPoint c => NURBSObj -> GLint -> Ptr GLfloat -> GLint -> Ptr GLfloat -> GLint -> GLint -> Ptr (c GLfloat) -> GLint -> GLint -> GL ()
+nurbsSurface nurbsObj sKnotCount sKnots tKnotCount tKnots sStride tStride control sOrder tOrder = liftIO $
+   gluNurbsSurface nurbsObj sKnotCount sKnots tKnotCount tKnots sStride tStride (castPtr control) sOrder tOrder (map2Target (pseudoPeek control))
+
+foreign import CALLCONV safe "gluNurbsSurface"
+   gluNurbsSurface :: NURBSObj -> GLint -> Ptr GLfloat -> GLint -> Ptr GLfloat -> GLint -> GLint -> Ptr GLfloat -> GLint -> GLint -> GLenum -> IO ()
+
+foreign import CALLCONV safe "gluEndSurface"
+   gluEndSurface :: NURBSObj -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 7.5: Trimming
+
+class TrimmingPoint p where
+   trimmingTarget :: p GLfloat -> GLenum
+
+instance TrimmingPoint Vertex2 where
+   trimmingTarget = marshalNURBSTrim . const Map1Trim2
+
+instance TrimmingPoint Vertex3 where
+   trimmingTarget = marshalNURBSTrim . const Map1Trim3
+
+data NURBSTrim =
+     Map1Trim2
+   | Map1Trim3
+
+marshalNURBSTrim :: NURBSTrim -> GLenum
+marshalNURBSTrim x = case x of
+   Map1Trim2 -> 100210
+   Map1Trim3 -> 100211
+
+nurbsBeginEndTrim :: NURBSObj -> GL a -> GL a
+nurbsBeginEndTrim nurbsObj x = liftIO $ 
+   bracket_ (gluBeginTrim nurbsObj) (gluEndTrim nurbsObj) (runGL x)
+
+foreign import CALLCONV safe "gluBeginTrim"
+   gluBeginTrim :: NURBSObj -> IO ()
+
+pwlCurve :: TrimmingPoint p => NURBSObj -> GLint -> Ptr (p GLfloat) -> GLint -> GL ()
+pwlCurve nurbsObj count points stride =
+   gluPwlCurve nurbsObj count (castPtr points) stride (trimmingTarget (pseudoPeek points))
+
+foreign import CALLCONV safe "gluPwlCurve"
+   gluPwlCurve :: NURBSObj -> GLint -> Ptr GLfloat -> GLint -> GLenum -> GL ()
+
+trimmingCurve :: TrimmingPoint c => NURBSObj -> GLint -> Ptr GLfloat -> GLint -> Ptr (c GLfloat) -> GLint -> GL ()
+trimmingCurve nurbsObj knotCount knots stride control order =
+   gluNurbsCurve nurbsObj knotCount knots stride (castPtr control) order (trimmingTarget (pseudoPeek control))
+
+foreign import CALLCONV safe "gluEndTrim"
+   gluEndTrim :: NURBSObj -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 7.6: NURBS Properties
+
+data NURBSProperty =
+     AutoLoadMatrix
+   | Culling
+   | ParametricTolerance
+   | SamplingTolerance
+   | DisplayMode'
+   | SamplingMethod
+   | UStep
+   | VStep
+   | NURBSMode
+
+marshalNURBSProperty :: NURBSProperty -> GLenum
+marshalNURBSProperty x = case x of
+   AutoLoadMatrix -> 100200
+   Culling -> 100201
+   ParametricTolerance -> 100202
+   SamplingTolerance -> 100203
+   DisplayMode' -> 100204
+   SamplingMethod -> 100205
+   UStep -> 100206
+   VStep -> 100207
+   NURBSMode -> 100160
+
+--------------------------------------------------------------------------------
+
+setNURBSProperty :: NURBSObj -> NURBSProperty -> GLfloat -> GL ()
+setNURBSProperty nurbsObj = gluNurbsProperty nurbsObj . marshalNURBSProperty
+
+foreign import CALLCONV safe "gluNurbsProperty"
+   gluNurbsProperty :: NURBSObj -> GLenum -> GLfloat -> GL ()
+
+--------------------------------------------------------------------------------
+
+data NURBSMode =
+     NURBSTessellator
+   | NURBSRenderer
+   deriving ( Eq, Ord, Show )
+
+marshalNURBSMode :: NURBSMode -> GLfloat
+marshalNURBSMode x = case x of
+   NURBSTessellator -> 100161
+   NURBSRenderer -> 100162
+
+setNURBSMode :: NURBSObj -> NURBSMode -> GL ()
+setNURBSMode nurbsObj = setNURBSProperty nurbsObj NURBSMode . marshalNURBSMode
+
+--------------------------------------------------------------------------------
+
+setNURBSCulling :: NURBSObj -> Capability -> GL ()
+setNURBSCulling nurbsObj = setNURBSProperty nurbsObj Culling . fromIntegral . marshalCapability
+
+--------------------------------------------------------------------------------
+
+data SamplingMethod' =
+     PathLength'
+   | ParametricError'
+   | DomainDistance'
+   | ObjectPathLength'
+   | ObjectParametricError'
+
+marshalSamplingMethod' :: SamplingMethod' -> GLfloat
+marshalSamplingMethod' x = case x of
+   PathLength' -> 100215
+   ParametricError' -> 100216
+   DomainDistance' -> 100217
+   ObjectPathLength' -> 100209
+   ObjectParametricError' -> 100208
+
+setSamplingMethod' :: NURBSObj -> SamplingMethod' -> GL ()
+setSamplingMethod' nurbsObj = setNURBSProperty nurbsObj SamplingMethod . marshalSamplingMethod'
+
+--------------------------------------------------------------------------------
+
+data SamplingMethod =
+     PathLength GLfloat
+   | ParametricError GLfloat
+   | DomainDistance GLfloat GLfloat
+   | ObjectPathLength GLfloat
+   | ObjectParametricError GLfloat
+   deriving ( Eq, Ord, Show )
+
+setSamplingMethod :: NURBSObj -> SamplingMethod -> GL ()
+setSamplingMethod nurbsObj x = case x of
+   PathLength s -> do
+      setNURBSProperty nurbsObj SamplingTolerance s
+      setSamplingMethod' nurbsObj PathLength'
+   ParametricError p -> do
+      setNURBSProperty nurbsObj ParametricTolerance p
+      setSamplingMethod' nurbsObj ParametricError'
+   DomainDistance u v -> do
+      setNURBSProperty nurbsObj UStep u
+      setNURBSProperty nurbsObj VStep v
+      setSamplingMethod' nurbsObj DomainDistance'
+   ObjectPathLength s -> do
+      setNURBSProperty nurbsObj SamplingTolerance s
+      setSamplingMethod' nurbsObj ObjectPathLength'
+   ObjectParametricError p -> do
+      setNURBSProperty nurbsObj ParametricTolerance p
+      setSamplingMethod' nurbsObj ObjectParametricError'
+
+--------------------------------------------------------------------------------
+
+setAutoLoadMatrix :: NURBSObj -> Bool -> IO ()
+setAutoLoadMatrix nurbsObj = runGL . setNURBSProperty nurbsObj AutoLoadMatrix . marshalGLboolean
+
+loadSamplingMatrices :: (Matrix m1, Matrix m2) => NURBSObj -> Maybe (m1 GLfloat, m2 GLfloat, (Position, Size)) -> GL ()
+loadSamplingMatrices nurbsObj = 
+   maybe
+      (liftIO $ setAutoLoadMatrix nurbsObj True)
+      (\(mv, proj, (Position x y, Size w h)) -> liftIO $ do
+          withMatrixColumnMajor mv $ \mvBuf ->
+             withMatrixColumnMajor proj $ \projBuf ->
+                withArray [x, y, w, h] $ \viewportBuf ->
+                  gluLoadSamplingMatrices nurbsObj mvBuf projBuf viewportBuf
+          setAutoLoadMatrix nurbsObj False)
+
+withMatrixColumnMajor :: (Matrix m, MatrixComponent c) => m c -> (Ptr c -> IO a) -> IO a
+withMatrixColumnMajor mat act =  runGL .
+   withMatrix mat $ \order p -> liftIO $
+      if order == ColumnMajor
+         then act p
+         else do
+            elems <- mapM (peekElemOff p) [ 0, 4,  8, 12,
+                                            1, 5,  9, 13,
+                                            2, 6, 10, 14,
+                                            3, 7, 11, 15 ]
+            withArray elems act
+
+foreign import CALLCONV safe "gluLoadSamplingMatrices"
+   gluLoadSamplingMatrices :: NURBSObj -> Ptr GLfloat -> Ptr GLfloat -> Ptr GLint -> IO ()
+
+--------------------------------------------------------------------------------
+
+data DisplayMode' =
+     Fill'
+   | OutlinePolygon
+   | OutlinePatch
+   deriving ( Eq, Ord, Show )
+
+marshalDisplayMode' :: DisplayMode' -> GLfloat
+marshalDisplayMode' x = case x of
+   Fill' -> 100012
+   OutlinePolygon -> 100240
+   OutlinePatch -> 100241
+
+setDisplayMode' :: NURBSObj -> DisplayMode' -> GL ()
+setDisplayMode' nurbsObj = setNURBSProperty nurbsObj DisplayMode' . marshalDisplayMode'
diff --git a/Graphics/Rendering/OGL/GLU/Quadrics.hs b/Graphics/Rendering/OGL/GLU/Quadrics.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GLU/Quadrics.hs
@@ -0,0 +1,213 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GLU.Quadrics
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to chapter 6 (Quadrics) of the GLU specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GLU.Quadrics (
+   QuadricNormal, QuadricTexture(..), QuadricOrientation(..),
+   QuadricDrawStyle(..), QuadricStyle(..),
+   Radius, Height, Angle, Slices, Stacks, Loops, QuadricPrimitive(..),
+   renderQuadric
+) where
+
+import Control.Monad ( unless )
+import Foreign.Ptr ( Ptr, nullPtr, FunPtr, freeHaskellFunPtr )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLboolean, GLenum, GLint, GLdouble )
+import Graphics.Rendering.OGL.GL.Colors ( ShadingModel(Smooth,Flat) )
+import Graphics.Rendering.OGL.GL.Exception ( bracket )
+import Graphics.Rendering.OGL.GL.GLboolean ( marshalGLboolean )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal (
+   recordErrorCode, recordOutOfMemory )
+
+--------------------------------------------------------------------------------
+
+data QuadricDrawStyle =
+     PointStyle
+   | LineStyle
+   | FillStyle
+   | SilhouetteStyle
+   deriving ( Eq, Ord, Show )
+
+marshalQuadricDrawStyle :: QuadricDrawStyle -> GLenum
+marshalQuadricDrawStyle x = case x of
+   PointStyle -> 0x186aa
+   LineStyle -> 0x186ab
+   FillStyle -> 0x186ac
+   SilhouetteStyle -> 0x186ad
+
+--------------------------------------------------------------------------------
+
+data QuadricCallback =
+     Error'2
+   deriving ( Eq, Ord, Show )
+
+marshalQuadricCallback :: QuadricCallback -> GLenum
+marshalQuadricCallback x = case x of
+   Error'2 -> 0x18707
+
+--------------------------------------------------------------------------------
+
+type QuadricNormal = Maybe ShadingModel
+
+marshalQuadricNormal :: QuadricNormal -> GLenum
+marshalQuadricNormal (Just Smooth) = 0x186a0
+marshalQuadricNormal (Just Flat  ) = 0x186a1
+marshalQuadricNormal Nothing       = 0x186a2
+
+--------------------------------------------------------------------------------
+
+data QuadricOrientation =
+     Outside
+   | Inside
+   deriving ( Eq, Ord, Show )
+
+marshalQuadricOrientation :: QuadricOrientation -> GLenum
+marshalQuadricOrientation x = case x of
+   Outside -> 0x186b4
+   Inside -> 0x186b5
+
+--------------------------------------------------------------------------------
+
+data QuadricTexture
+   = NoTextureCoordinates
+   | GenerateTextureCoordinates
+   deriving ( Eq,Ord )
+
+marshalQuadricTexture :: QuadricTexture -> GLboolean
+marshalQuadricTexture NoTextureCoordinates       = marshalGLboolean False
+marshalQuadricTexture GenerateTextureCoordinates = marshalGLboolean True
+
+--------------------------------------------------------------------------------
+
+data QuadricStyle
+   = QuadricStyle QuadricNormal
+                  QuadricTexture
+                  QuadricOrientation
+                  QuadricDrawStyle
+   deriving ( Eq,Ord )
+
+--------------------------------------------------------------------------------
+
+type Radius = GLdouble
+type Height = GLdouble
+type Angle  = GLdouble
+type Slices = GLint
+type Stacks = GLint
+type Loops  = GLint
+
+--------------------------------------------------------------------------------
+
+data QuadricPrimitive
+   = Sphere Radius Slices Stacks
+   | Cylinder Radius Radius Height Slices Stacks
+   | Disk Radius Radius Slices Loops
+   | PartialDisk Radius Radius Slices Loops Angle Angle
+   deriving ( Eq, Ord )
+
+--------------------------------------------------------------------------------
+
+renderQuadric :: QuadricStyle -> QuadricPrimitive -> GL ()
+renderQuadric style prim = liftIO $ do
+   withQuadricObj recordOutOfMemory $ \quadricObj ->
+      withErrorCallback quadricObj recordErrorCode $ do
+         setStyle quadricObj style
+         renderPrimitive quadricObj prim
+
+withQuadricObj :: IO a -> (QuadricObj -> IO a) -> IO a
+withQuadricObj failure success =
+   bracket gluNewQuadric safeDeleteQuadric
+           (\quadricObj -> if isNullQuadricObj quadricObj
+                              then failure
+                              else success quadricObj)
+
+withErrorCallback :: QuadricObj -> QuadricCallback' -> IO a -> IO a
+withErrorCallback quadricObj callback action =
+   bracket (makeQuadricCallback callback) freeHaskellFunPtr $ \callbackPtr -> do
+      gluQuadricCallback quadricObj (marshalQuadricCallback Error'2) callbackPtr
+      action
+
+setStyle :: QuadricObj -> QuadricStyle -> IO ()
+setStyle quadricObj (QuadricStyle n t o d) = do
+   gluQuadricNormals     quadricObj (marshalQuadricNormal      n)
+   gluQuadricTexture     quadricObj (marshalQuadricTexture     t)
+   gluQuadricOrientation quadricObj (marshalQuadricOrientation o)
+   gluQuadricDrawStyle   quadricObj (marshalQuadricDrawStyle   d)
+
+renderPrimitive :: QuadricObj -> QuadricPrimitive -> IO ()
+renderPrimitive quadricObj (Sphere r s n) =
+   gluSphere quadricObj r s n
+renderPrimitive quadricObj (Cylinder b t h s n) =
+   gluCylinder quadricObj b t h s n
+renderPrimitive quadricObj (Disk i o s l) =
+   gluDisk quadricObj i o s l
+renderPrimitive quadricObj (PartialDisk i o s l a w) =
+   gluPartialDisk quadricObj i o s l a w
+
+--------------------------------------------------------------------------------
+
+-- 'Char' is a fake here, any marshalable type would do
+newtype QuadricObj = QuadricObj (Ptr Char)
+   deriving ( Eq )
+
+isNullQuadricObj :: QuadricObj -> Bool
+isNullQuadricObj = (QuadricObj nullPtr ==)
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "gluNewQuadric" gluNewQuadric :: IO QuadricObj
+
+safeDeleteQuadric :: QuadricObj -> IO ()
+safeDeleteQuadric quadricObj =
+   unless (isNullQuadricObj quadricObj) $ gluDeleteQuadric quadricObj
+
+foreign import CALLCONV unsafe "gluDeleteQuadric" gluDeleteQuadric ::
+   QuadricObj -> IO ()
+
+--------------------------------------------------------------------------------
+
+type QuadricCallback' = GLenum -> IO ()
+
+foreign import CALLCONV "wrapper" makeQuadricCallback ::
+   QuadricCallback' -> IO (FunPtr QuadricCallback')
+
+foreign import CALLCONV unsafe "gluQuadricCallback" gluQuadricCallback ::
+   QuadricObj -> GLenum -> FunPtr QuadricCallback' -> IO ()
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV unsafe "gluQuadricNormals" gluQuadricNormals ::
+   QuadricObj -> GLenum -> IO ()
+
+foreign import CALLCONV unsafe "gluQuadricTexture" gluQuadricTexture ::
+   QuadricObj -> GLboolean -> IO ()
+
+foreign import CALLCONV unsafe "gluQuadricOrientation" gluQuadricOrientation ::
+   QuadricObj -> GLenum -> IO ()
+
+foreign import CALLCONV unsafe "gluQuadricDrawStyle" gluQuadricDrawStyle ::
+   QuadricObj -> GLenum -> IO ()
+
+--------------------------------------------------------------------------------
+
+foreign import CALLCONV safe "gluSphere" gluSphere ::
+   QuadricObj -> Radius -> Slices -> Stacks -> IO ()
+
+foreign import CALLCONV safe "gluCylinder" gluCylinder ::
+  QuadricObj -> Radius -> Radius -> Height -> Slices -> Stacks -> IO ()
+
+foreign import CALLCONV safe "gluDisk" gluDisk ::
+   QuadricObj -> Radius -> Radius -> Slices -> Loops -> IO ()
+
+foreign import CALLCONV safe "gluPartialDisk" gluPartialDisk ::
+   QuadricObj -> Radius -> Radius -> Slices -> Loops -> Angle -> Angle -> IO ()
diff --git a/Graphics/Rendering/OGL/GLU/Tessellation.hs b/Graphics/Rendering/OGL/GLU/Tessellation.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/GLU/Tessellation.hs
@@ -0,0 +1,698 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.GLU.Tessellation
+-- Copyright   :  (c) Sven Panne 2002-2006
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module corresponds to chapter 5 (Polygon Tessellation) of the GLU specs.
+--
+--------------------------------------------------------------------------------
+
+module Graphics.Rendering.OGL.GLU.Tessellation (
+   -- * Polygon description
+   AnnotatedVertex(..), ComplexContour(..), ComplexPolygon(..),
+
+   -- * Combining vertices
+   WeightedProperties(..), Combiner,
+
+   -- * Tessellation parameters
+   TessWinding(..), Tolerance,
+
+   -- * Tessellator type
+   Tessellator,
+
+   -- * Contour extractionx
+   SimpleContour(..), PolygonContours(..), extractContours,
+
+   -- * Triangulation
+   TriangleVertex, Triangle(..), Triangulation(..), triangulate,
+
+   -- * Tessellation into primitives
+   Primitive(..), SimplePolygon(..), tessellate
+) where
+
+import Control.Monad ( foldM, unless )
+import Data.IORef ( newIORef, readIORef, writeIORef, modifyIORef )
+import Foreign.Marshal.Alloc ( allocaBytes )
+import Foreign.Marshal.Array ( peekArray, pokeArray )
+import Foreign.Marshal.Pool ( Pool, withPool, pooledNew )
+import Foreign.Ptr ( Ptr, nullPtr, plusPtr, castPtr, FunPtr, freeHaskellFunPtr )
+import Foreign.Storable ( Storable(..) )
+import Graphics.Rendering.OGL.Monad
+import Graphics.Rendering.OGL.GL.BasicTypes (
+   GLboolean, GLclampf, GLdouble, GLenum )
+import Graphics.Rendering.OGL.GL.EdgeFlag ( unmarshalEdgeFlag )
+import Graphics.Rendering.OGL.GL.Exception ( bracket )
+import Graphics.Rendering.OGL.GL.GLboolean ( marshalGLboolean )
+import Graphics.Rendering.OGL.GL.PrimitiveMode ( unmarshalPrimitiveMode )
+import Graphics.Rendering.OGL.GL.BeginEnd (
+   PrimitiveMode, EdgeFlag(BeginsInteriorEdge) )
+import Graphics.Rendering.OGL.GL.VertexSpec (
+   Vertex3(..), Normal3(..) )
+import Graphics.Rendering.OGL.GLU.ErrorsInternal (
+   recordErrorCode, recordOutOfMemory )
+
+--------------------------------------------------------------------------------
+
+data TessCallback =
+     TessBegin
+   | Begin
+   | TessVertex
+   | Vertex
+   | TessEnd
+   | End
+   | TessError
+   | Error'
+   | TessEdgeFlag
+   | EdgeFlag
+   | TessCombine
+   | TessBeginData
+   | TessVertexData
+   | TessEndData
+   | TessErrorData
+   | TessEdgeFlagData
+   | TessCombineData
+
+marshalTessCallback :: TessCallback -> GLenum
+marshalTessCallback x = case x of
+   TessBegin -> 0x18704
+   Begin -> 0x18704
+   TessVertex -> 0x18705
+   Vertex -> 0x18705
+   TessEnd -> 0x18706
+   End -> 0x18706
+   TessError -> 0x18707
+   Error' -> 0x18707
+   TessEdgeFlag -> 0x18708
+   EdgeFlag -> 0x18708
+   TessCombine -> 0x18709
+   TessBeginData -> 0x1870a
+   TessVertexData -> 0x1870b
+   TessEndData -> 0x1870c
+   TessErrorData -> 0x1870d
+   TessEdgeFlagData -> 0x1870e
+   TessCombineData -> 0x1870f
+
+--------------------------------------------------------------------------------
+
+data TessProperty =
+     TessWindingRule
+   | TessBoundaryOnly
+   | TessTolerance
+
+marshalTessProperty :: TessProperty -> GLenum
+marshalTessProperty x = case x of
+   TessWindingRule -> 0x1872c
+   TessBoundaryOnly -> 0x1872d
+   TessTolerance -> 0x1872e
+
+--------------------------------------------------------------------------------
+
+data TessWinding =
+     TessWindingOdd
+   | TessWindingNonzero
+   | TessWindingPositive
+   | TessWindingNegative
+   | TessWindingAbsGeqTwo
+   deriving ( Eq, Ord, Show )
+
+marshalTessWinding :: TessWinding -> GLenum
+marshalTessWinding x = case x of
+   TessWindingOdd -> 0x18722
+   TessWindingNonzero -> 0x18723
+   TessWindingPositive -> 0x18724
+   TessWindingNegative -> 0x18725
+   TessWindingAbsGeqTwo -> 0x18726
+
+--------------------------------------------------------------------------------
+
+-- | The basic building block in tessellation is a 3D vertex with an associated
+-- property, e.g. color, texture coordinates, etc.
+
+data AnnotatedVertex v = AnnotatedVertex (Vertex3 GLdouble) v
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq v => Eq (AnnotatedVertex v)
+instance Ord v => Ord (AnnotatedVertex v)
+#else
+   deriving ( Eq, Ord )
+#endif
+
+offsetOfProperty :: Storable v => v -> Int
+offsetOfProperty v = alignOffset v (3 * sizeOf x)
+   where AnnotatedVertex (Vertex3 x _ _) _ = undefined
+
+alignOffset :: Storable a => a -> Int -> Int
+alignOffset x offset = n - (n `mod` a)
+   where a = alignment x
+         n = a + offset - 1
+
+instance Storable v => Storable (AnnotatedVertex v) where
+
+   sizeOf ~(AnnotatedVertex (Vertex3 x _ _) v) =
+      alignOffset x (sizeOf v + offsetOfProperty v)
+
+   alignment ~(AnnotatedVertex (Vertex3 x _ _) _) =
+      alignment x
+
+   peek ptr = do
+      x <- peekElemOff (castPtr ptr) 0
+      y <- peekElemOff (castPtr ptr) 1
+      z <- peekElemOff (castPtr ptr) 2
+      let dummyElement :: Ptr (AnnotatedVertex v) -> v
+          dummyElement = undefined
+      v <- peekByteOff (castPtr ptr) (offsetOfProperty (dummyElement ptr))
+      return $ AnnotatedVertex (Vertex3 x y z) v
+
+   poke ptr (AnnotatedVertex (Vertex3 x y z) v) = do
+      pokeElemOff (castPtr ptr) 0 x
+      pokeElemOff (castPtr ptr) 1 y
+      pokeElemOff (castPtr ptr) 2 z
+      pokeByteOff (castPtr ptr) (offsetOfProperty v) v
+
+--------------------------------------------------------------------------------
+
+-- | A complex contour, which can be self-intersecting and\/or concave.
+
+newtype ComplexContour v = ComplexContour [AnnotatedVertex v]
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq v => Eq (ComplexContour v)
+instance Ord v => Ord (ComplexContour v)
+#else
+   deriving ( Eq, Ord )
+#endif
+
+sizeOfComplexContour :: Storable v => ComplexContour v -> Int
+sizeOfComplexContour (ComplexContour vs) =
+   length vs * sizeOf (head vs)
+
+pokeComplexContour ::
+   Storable v => Ptr (ComplexContour v) -> ComplexContour v -> IO ()
+pokeComplexContour ptr (ComplexContour vs) =
+   pokeArray (castPtr ptr) vs
+
+--------------------------------------------------------------------------------
+
+-- | A complex (possibly concave) polygon, represented by one or more complex
+-- and possibly intersecting contours.
+
+newtype ComplexPolygon v = ComplexPolygon [ComplexContour v]
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq v => Eq (ComplexPolygon v)
+instance Ord v => Ord (ComplexPolygon v)
+#else
+   deriving ( Eq, Ord )
+#endif
+
+sizeOfComplexPolygon :: Storable v => ComplexPolygon v -> Int
+sizeOfComplexPolygon (ComplexPolygon complexContours) =
+   sum (map sizeOfComplexContour complexContours)
+
+pokeComplexPolygon ::
+   Storable v => Ptr (ComplexPolygon v) -> ComplexPolygon v -> IO ()
+pokeComplexPolygon ptr (ComplexPolygon complexContours) =
+   foldM pokeAndAdvance (castPtr ptr) complexContours >> return ()
+   where pokeAndAdvance p complexContour = do
+            pokeComplexContour p complexContour
+            return $ p `plusPtr` sizeOfComplexContour complexContour
+
+withComplexPolygon ::
+   Storable v => ComplexPolygon v -> (Ptr (ComplexPolygon v) -> IO a) -> IO a
+withComplexPolygon complexPolygon f =
+   allocaBytes (sizeOfComplexPolygon complexPolygon) $ \ptr -> do
+      pokeComplexPolygon ptr complexPolygon
+      f ptr
+
+--------------------------------------------------------------------------------
+
+-- | Four vertex properties (cf. 'AnnotatedVertex') with associated weigths
+-- summing up to 1.0.
+
+data WeightedProperties v
+   = WeightedProperties (GLclampf, v)
+                        (GLclampf, v)
+                        (GLclampf, v)
+                        (GLclampf, v)
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq v => Eq (WeightedProperties v)
+instance Ord v => Ord (WeightedProperties v)
+#else
+   deriving ( Eq, Ord )
+#endif
+
+-- | A function combining given vertex properties into a property for a newly
+-- generated vertex
+
+type Combiner v
+    = Vertex3 GLdouble
+   -> WeightedProperties v
+   -> v
+
+--------------------------------------------------------------------------------
+
+-- | The relative tolerance under which two vertices can be combined (see
+-- 'Combiner'). Multiplication with the largest coordinate magnitude of all
+-- polygon vertices yields the maximum distance between two mergeable vertices.
+--
+-- Note that merging is optional and the tolerance is only a hint.
+
+type Tolerance = GLdouble
+
+--------------------------------------------------------------------------------
+
+-- | A general tessellator type.
+--
+-- Before tessellation of a complex polygon, all its vertices are projected into
+-- a plane perpendicular to the given normal. If the given normal is
+-- @Normal3 0 0 0@, a fitting plane of all vertices is used.
+
+type Tessellator p v
+   = TessWinding
+  -> Tolerance
+  -> Normal3 GLdouble
+  -> Combiner v
+  -> ComplexPolygon v
+  -> GL (p v)
+
+--------------------------------------------------------------------------------
+
+-- | A simple, non-self-intersecting contour
+
+newtype SimpleContour v = SimpleContour [AnnotatedVertex v]
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq v => Eq (SimpleContour v)
+instance Ord v => Ord (SimpleContour v)
+#else
+   deriving ( Eq, Ord )
+#endif
+
+-- | The contours of a complex polygon, represented by one or more
+-- non-intersecting simple contours
+
+newtype PolygonContours v = PolygonContours [SimpleContour v]
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq v => Eq (PolygonContours v)
+instance Ord v => Ord (PolygonContours v)
+#else
+   deriving ( Eq, Ord )
+#endif
+
+extractContours :: Storable v => Tessellator PolygonContours v
+extractContours windingRule tolerance normal combiner complexPoly = liftIO $ do
+
+   vertices <- newIORef []
+   let addVertex v = modifyIORef vertices (v:)
+
+   contours <- newIORef []
+   let finishContour = do
+          vs <- readIORef vertices
+          writeIORef vertices []
+          modifyIORef contours (SimpleContour (reverse vs) :)
+
+       getContours = fmap (PolygonContours . reverse) (readIORef contours)
+
+   withTessellatorObj (PolygonContours [])$ \tessObj -> do
+      setTessellatorProperties tessObj windingRule tolerance normal True
+      withVertexCallback tessObj addVertex $
+         withEndCallback tessObj finishContour $
+            checkForError tessObj $
+               withCombineCallback tessObj combiner $ do
+                  defineComplexPolygon tessObj complexPoly
+                  getContours
+
+--------------------------------------------------------------------------------
+
+-- | A triangle vertex with additional information about the edge it begins
+
+type TriangleVertex v = AnnotatedVertex (v,EdgeFlag)
+
+-- | A triangle, represented by three triangle vertices
+
+data Triangle v
+   = Triangle (TriangleVertex v) (TriangleVertex v) (TriangleVertex v)
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq v => Eq (Triangle v)
+instance Ord v => Ord (Triangle v)
+#else
+   deriving ( Eq, Ord )
+#endif
+
+-- | A triangulation of a complex polygon
+
+newtype Triangulation v = Triangulation [Triangle v]
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq v => Eq (Triangulation v)
+instance Ord v => Ord (Triangulation v)
+#else
+   deriving ( Eq, Ord )
+#endif
+
+triangulate :: Storable v => Tessellator Triangulation v
+triangulate windingRule tolerance normal combiner complexPoly = liftIO $ do
+
+   edgeFlagState <- newIORef BeginsInteriorEdge
+   let registerEdgeFlag = writeIORef edgeFlagState
+
+   vertices <- newIORef []
+   let addVertex (AnnotatedVertex xyz v) = do
+          ef <- readIORef edgeFlagState
+          modifyIORef vertices (AnnotatedVertex xyz (v,ef) :)
+
+       getTriangulation = do
+          vs <- readIORef vertices
+          return $ Triangulation (collectTriangles (reverse vs))
+
+   withTessellatorObj (Triangulation []) $ \tessObj -> do
+      setTessellatorProperties tessObj windingRule tolerance normal False
+      withEdgeFlagCallback tessObj registerEdgeFlag $
+         withVertexCallback tessObj addVertex $
+            checkForError tessObj $
+               withCombineCallback tessObj combiner $ do
+                  defineComplexPolygon tessObj complexPoly
+                  getTriangulation
+
+collectTriangles :: [TriangleVertex v] -> [Triangle v]
+collectTriangles []           = []
+collectTriangles (a:b:c:rest) = Triangle a b c : collectTriangles rest
+collectTriangles _            = error "triangles left"
+
+--------------------------------------------------------------------------------
+
+data Primitive v = Primitive PrimitiveMode [AnnotatedVertex v]
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq v => Eq (Primitive v)
+instance Ord v => Ord (Primitive v)
+#else
+   deriving ( Eq, Ord )
+#endif
+
+newtype SimplePolygon v = SimplePolygon [Primitive v]
+#ifdef __HADDOCK__
+-- Help Haddock a bit, because it doesn't do any instance inference.
+instance Eq v => Eq (SimplePolygon v)
+instance Ord v => Ord (SimplePolygon v)
+#else
+   deriving ( Eq, Ord )
+#endif
+
+tessellate :: Storable v => Tessellator SimplePolygon v
+tessellate windingRule tolerance normal combiner complexPoly = liftIO $ do
+
+   beginModeState <- newIORef undefined
+   let setPrimitiveMode = writeIORef beginModeState
+
+   vertices <- newIORef []
+   let addVertex v = modifyIORef vertices (v:)
+
+   primitives <- newIORef []
+   let finishPrimitive = do
+          beginMode <- readIORef beginModeState
+          vs <- readIORef vertices
+          writeIORef vertices []
+          modifyIORef primitives (Primitive beginMode (reverse vs) :)
+
+       getSimplePolygon = fmap (SimplePolygon . reverse) (readIORef primitives)
+
+   withTessellatorObj (SimplePolygon []) $ \tessObj -> do
+      setTessellatorProperties tessObj windingRule tolerance normal False
+      withBeginCallback tessObj setPrimitiveMode $
+         withVertexCallback tessObj addVertex $
+            withEndCallback tessObj finishPrimitive $
+               checkForError tessObj $
+                  withCombineCallback tessObj combiner $ do
+                     defineComplexPolygon tessObj complexPoly
+                     getSimplePolygon
+
+--------------------------------------------------------------------------------
+-- chapter 5.1: The Tessellation Object
+
+-- an opaque pointer to a tessellator object
+newtype TessellatorObj = TessellatorObj (Ptr TessellatorObj)
+
+isNullTesselatorObj :: TessellatorObj -> Bool
+isNullTesselatorObj (TessellatorObj ptr) = ptr == nullPtr
+
+withTessellatorObj :: a -> (TessellatorObj -> IO a) -> IO a
+withTessellatorObj failureValue action =
+   bracket gluNewTess safeDeleteTess
+           (\tessObj -> if isNullTesselatorObj tessObj
+                           then do recordOutOfMemory
+                                   return failureValue
+                           else action tessObj)
+
+foreign import CALLCONV unsafe "gluNewTess" gluNewTess :: IO TessellatorObj
+
+safeDeleteTess :: TessellatorObj -> IO ()
+safeDeleteTess tessObj =
+   unless (isNullTesselatorObj tessObj) $ gluDeleteTess tessObj
+
+foreign import CALLCONV unsafe "gluDeleteTess" gluDeleteTess ::
+   TessellatorObj -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 5.2: Polygon Definition (polygons)
+
+defineComplexPolygon ::
+   Storable v => TessellatorObj -> ComplexPolygon v -> IO ()
+defineComplexPolygon tessObj cp@(ComplexPolygon complexContours) =
+   withComplexPolygon cp $ \ptr ->
+      tessBeginEndPolygon tessObj nullPtr $
+         let loop _ []     = return ()
+             loop p (c:cs) = do defineComplexContour tessObj (castPtr p) c
+                                loop (p `plusPtr` sizeOfComplexContour c) cs
+         in loop ptr complexContours
+
+tessBeginEndPolygon :: TessellatorObj -> Ptr p -> IO a -> IO a
+tessBeginEndPolygon tessObj ptr f = do
+   gluTessBeginPolygon tessObj ptr
+   res <- f
+   gluTessEndPolygon tessObj
+   return res
+
+foreign import CALLCONV safe "gluTessBeginPolygon" gluTessBeginPolygon ::
+   TessellatorObj -> Ptr p -> IO ()
+
+foreign import CALLCONV safe "gluTessEndPolygon" gluTessEndPolygon ::
+   TessellatorObj -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 5.2: Polygon Definition (contours)
+
+defineComplexContour ::
+   Storable v =>
+   TessellatorObj -> Ptr (ComplexContour v) -> ComplexContour v -> IO ()
+defineComplexContour tessObj ptr (ComplexContour annotatedVertices) =
+   tessBeginEndContour tessObj $
+         let loop _ []     = return ()
+             loop p (v:vs) = do defineVertex tessObj (castPtr p)
+                                loop (p `plusPtr` sizeOf v) vs
+         in loop ptr annotatedVertices
+
+tessBeginEndContour :: TessellatorObj -> IO a -> IO a
+tessBeginEndContour tessObj f = do
+   gluTessBeginContour tessObj
+   res <- f
+   gluTessEndContour tessObj
+   return res
+
+foreign import CALLCONV safe "gluTessBeginContour" gluTessBeginContour ::
+   TessellatorObj -> IO ()
+
+foreign import CALLCONV safe "gluTessEndContour" gluTessEndContour ::
+   TessellatorObj -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 5.2: Polygon Definition (vertices)
+
+defineVertex :: TessellatorObj -> Ptr (AnnotatedVertex v) -> IO ()
+defineVertex tessObj ptr = gluTessVertex tessObj (castPtr ptr) ptr
+
+foreign import CALLCONV safe "gluTessVertex" gluTessVertex ::
+   TessellatorObj -> Ptr (Vertex3 GLdouble) -> Ptr (AnnotatedVertex v) -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 5.3: Callbacks (begin)
+
+type BeginCallback  = PrimitiveMode -> IO ()
+
+type BeginCallback' = GLenum -> IO ()
+
+withBeginCallback :: TessellatorObj -> BeginCallback -> IO a -> IO a
+withBeginCallback tessObj beginCallback action =
+   bracket (makeBeginCallback (beginCallback . unmarshalPrimitiveMode))
+           freeHaskellFunPtr $ \callbackPtr -> do
+      setBeginCallback tessObj (marshalTessCallback TessBegin) callbackPtr
+      action
+
+foreign import CALLCONV "wrapper" makeBeginCallback ::
+   BeginCallback' -> IO (FunPtr BeginCallback')
+
+foreign import CALLCONV unsafe "gluTessCallback" setBeginCallback ::
+   TessellatorObj -> GLenum -> FunPtr BeginCallback' -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 5.3: Callbacks (edgeFlag)
+
+type EdgeFlagCallback  = EdgeFlag -> IO ()
+
+type EdgeFlagCallback' = GLboolean -> IO ()
+
+withEdgeFlagCallback :: TessellatorObj -> EdgeFlagCallback -> IO a -> IO a
+withEdgeFlagCallback tessObj edgeFlagCallback action =
+   bracket (makeEdgeFlagCallback (edgeFlagCallback . unmarshalEdgeFlag))
+           freeHaskellFunPtr $ \callbackPtr -> do
+      setEdgeFlagCallback tessObj (marshalTessCallback TessEdgeFlag) callbackPtr
+      action
+
+foreign import CALLCONV "wrapper" makeEdgeFlagCallback ::
+   EdgeFlagCallback' -> IO (FunPtr EdgeFlagCallback')
+
+foreign import CALLCONV unsafe "gluTessCallback" setEdgeFlagCallback ::
+   TessellatorObj -> GLenum -> FunPtr EdgeFlagCallback' -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 5.3: Callbacks (vertex)
+
+type VertexCallback v = AnnotatedVertex v -> IO ()
+
+type VertexCallback' v = Ptr (AnnotatedVertex v) -> IO ()
+
+withVertexCallback ::
+   Storable v => TessellatorObj -> VertexCallback v -> IO a -> IO a
+withVertexCallback tessObj vertexCallback action =
+   bracket (makeVertexCallback (\p -> peek p >>= vertexCallback))
+           freeHaskellFunPtr $ \callbackPtr -> do
+      setVertexCallback tessObj (marshalTessCallback TessVertex) callbackPtr
+      action
+
+foreign import CALLCONV "wrapper" makeVertexCallback ::
+   VertexCallback' v -> IO (FunPtr (VertexCallback' v))
+
+foreign import CALLCONV unsafe "gluTessCallback" setVertexCallback ::
+   TessellatorObj -> GLenum -> FunPtr (VertexCallback' v) -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 5.3: Callbacks (end)
+
+type EndCallback  = IO ()
+
+withEndCallback :: TessellatorObj -> EndCallback -> IO a -> IO a
+withEndCallback tessObj endCallback action =
+   bracket (makeEndCallback endCallback) freeHaskellFunPtr $ \callbackPtr -> do
+      setEndCallback tessObj (marshalTessCallback TessEnd) callbackPtr
+      action
+
+foreign import CALLCONV "wrapper" makeEndCallback ::
+   EndCallback -> IO (FunPtr EndCallback)
+
+foreign import CALLCONV unsafe "gluTessCallback" setEndCallback ::
+   TessellatorObj -> GLenum -> FunPtr EndCallback -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 5.3: Callbacks (error)
+
+type ErrorCallback = GLenum -> IO ()
+
+withErrorCallback :: TessellatorObj -> ErrorCallback -> IO a -> IO a
+withErrorCallback tessObj errorCallback action =
+   bracket (makeErrorCallback errorCallback)
+           freeHaskellFunPtr $ \callbackPtr -> do
+      setErrorCallback tessObj (marshalTessCallback TessError) callbackPtr
+      action
+
+foreign import CALLCONV "wrapper" makeErrorCallback ::
+   ErrorCallback -> IO (FunPtr ErrorCallback)
+
+foreign import CALLCONV unsafe "gluTessCallback" setErrorCallback ::
+   TessellatorObj -> GLenum -> FunPtr ErrorCallback -> IO ()
+
+checkForError :: TessellatorObj -> IO a -> IO a
+checkForError tessObj = withErrorCallback tessObj recordErrorCode
+
+--------------------------------------------------------------------------------
+-- chapter 5.3: Callbacks (combine)
+
+type CombineCallback v =
+      Ptr (Vertex3 GLdouble)
+   -> Ptr (Ptr (AnnotatedVertex v))
+   -> Ptr GLclampf
+   -> Ptr (Ptr (AnnotatedVertex v))
+   -> IO ()
+
+withCombineCallback ::
+   Storable v => TessellatorObj -> Combiner v -> IO a -> IO a
+withCombineCallback tessObj combiner action =
+   withPool $ \vertexPool ->
+      bracket (makeCombineCallback (combineProperties vertexPool combiner))
+              freeHaskellFunPtr $ \callbackPtr -> do
+         setCombineCallback tessObj (marshalTessCallback TessCombine) callbackPtr
+         action 
+
+combineProperties :: Storable v => Pool -> Combiner v -> CombineCallback v
+combineProperties pool combiner newVertexPtr propertyPtrs weights result = do
+   newVertex <- peek newVertexPtr
+   [v0, v1, v2, v3] <- mapM (getProperty propertyPtrs) [0..3]
+   [w0, w1, w2, w3] <- peekArray 4 weights
+   let wp = WeightedProperties (w0,v0) (w1,v1) (w2,v2) (w3,v3)
+       av = AnnotatedVertex newVertex (combiner newVertex wp)
+   poke result =<< pooledNew pool av
+
+getProperty :: Storable v => Ptr (Ptr (AnnotatedVertex v)) -> Int -> IO v
+getProperty propertyPtrs n = do
+   AnnotatedVertex _ v <- peek =<< peekElemOff propertyPtrs n
+   return v
+
+foreign import CALLCONV "wrapper" makeCombineCallback ::
+   CombineCallback v -> IO (FunPtr (CombineCallback v))
+
+foreign import CALLCONV unsafe "gluTessCallback" setCombineCallback ::
+   TessellatorObj -> GLenum -> FunPtr (CombineCallback v) -> IO ()
+
+--------------------------------------------------------------------------------
+-- chapter 5.4: Control over Tessellation
+
+setTessellatorProperties ::
+    TessellatorObj -> TessWinding -> Tolerance -> Normal3 GLdouble -> Bool
+ -> IO ()
+setTessellatorProperties tessObj windingRule tolerance normal boundaryOnly = do
+   setWindingRule tessObj windingRule
+   setTolerance tessObj tolerance
+   setNormal tessObj normal
+   setBoundaryOnly tessObj boundaryOnly
+
+setWindingRule :: TessellatorObj -> TessWinding -> IO ()
+setWindingRule tessObj =
+   tessProperty tessObj TessWindingRule . fromIntegral . marshalTessWinding
+
+setBoundaryOnly :: TessellatorObj -> Bool -> IO ()
+setBoundaryOnly tessObj =
+   tessProperty tessObj TessBoundaryOnly . marshalGLboolean
+
+setTolerance :: TessellatorObj -> Tolerance -> IO ()
+setTolerance tessObj =
+   tessProperty tessObj TessTolerance
+
+tessProperty :: TessellatorObj -> TessProperty -> GLdouble -> IO ()
+tessProperty tessObj =
+   gluTessProperty tessObj . marshalTessProperty
+
+foreign import CALLCONV unsafe "gluTessProperty" gluTessProperty ::
+   TessellatorObj -> GLenum -> GLdouble -> IO ()
+
+setNormal :: TessellatorObj -> Normal3 GLdouble -> IO ()
+setNormal tessObj (Normal3 x y z) = gluTessNormal tessObj x y z
+
+foreign import CALLCONV unsafe "gluTessNormal" gluTessNormal ::
+   TessellatorObj -> GLdouble -> GLdouble -> GLdouble -> IO ()
diff --git a/Graphics/Rendering/OGL/Monad.hs b/Graphics/Rendering/OGL/Monad.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/OGL/Monad.hs
@@ -0,0 +1,47 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Graphics.Rendering.OGL.Monad
+-- Copyright   :  (c) Neal Alexander 2008
+-- License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+-- 
+-- Maintainer  :  relapse.dev@gmx.com
+-- Stability   :  experimental
+-- Portability :  ghc
+-- 
+-- GL Contexts:
+-- 
+-- - 'MonadGL' a command that can be used in any OpenGL context.
+-- 
+-- - 'GL' a basic command that cannot be used between begin\/end.
+-- 
+-- - 'PrimitiveGL' a primitive command sent during begin\/end context.
+-- 
+
+module Graphics.Rendering.OGL.Monad (liftIO, runGL, runGLA, GL, runPrimitive, PrimitiveGL, MonadGL) where 
+
+import Control.Monad
+import Control.Applicative
+import Control.Monad.Trans
+import Control.Arrow
+
+class MonadIO m => MonadGL m
+
+instance MonadGL GL
+instance MonadGL PrimitiveGL
+
+newtype GL a = GL (IO a) deriving (Functor, Monad, MonadIO)
+newtype PrimitiveGL a = PrimitiveGL (IO a) deriving (Functor, Monad, MonadIO)
+
+
+
+runGL :: GL a -> IO a
+runGL (GL x) = x
+
+-- | arrow version of runGL
+runGLA :: Kleisli GL a a -> Kleisli IO a a
+runGLA a = Kleisli $ runGL . runKleisli a
+
+
+-- | This is used internally and shouldnt be needed by the user.
+runPrimitive :: PrimitiveGL a -> IO a
+runPrimitive (PrimitiveGL x) = x
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2002-2005, Sven Panne
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the author nor the names of its contributors may be
+   used to endorse or promote products derived from this software without
+   specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/OGL.cabal b/OGL.cabal
new file mode 100644
--- /dev/null
+++ b/OGL.cabal
@@ -0,0 +1,117 @@
+name:		OGL
+version:	0.0.0
+license:	BSD3
+license-file:	LICENSE
+maintainer:	Neal Alexander <relapse.dev@gmx.com>
+homepage:	http://haskell.org/haskellwiki/OGL
+stability:	experimental
+category:	Graphics
+build-type:	Configure
+synopsis:	A context aware binding for the OpenGL graphics system
+description:
+    A fork of the hOpenGL 2.2.1.1 package.
+
+    Modifications to OpenGL IO using the -XGeneralizedNewtypeDeriving extension create context sensitive MonadIO aliases. 
+
+	
+extra-source-files:
+	config.guess config.sub install-sh
+	configure.ac configure config.mk.in OpenGL.buildinfo.in
+        include/HsOpenGLConfig.h.in include/HsOpenGL.h.in
+	include/HsOpenGLExt.h include/HsOpenGLTypes.h
+extra-tmp-files:
+	config.log config.status autom4te.cache
+	config.mk OpenGL.buildinfo include/HsOpenGLConfig.h include/HsOpenGL.h
+exposed-modules:
+	Graphics.Rendering.OGL.Monad
+	Graphics.Rendering.OGL.GL.Antialiasing,
+	Graphics.Rendering.OGL.GL.BasicTypes,
+	Graphics.Rendering.OGL.GL.BeginEnd,
+	Graphics.Rendering.OGL.GL.Bitmaps,
+	Graphics.Rendering.OGL.GL.BufferObjects,
+	Graphics.Rendering.OGL.GL.Clipping,
+	Graphics.Rendering.OGL.GL.Colors,
+	Graphics.Rendering.OGL.GL.ColorSum,
+	Graphics.Rendering.OGL.GL.CoordTrans,
+	Graphics.Rendering.OGL.GL.DisplayLists,
+	Graphics.Rendering.OGL.GL.Evaluators,
+	Graphics.Rendering.OGL.GL.Feedback,
+	Graphics.Rendering.OGL.GL.FlushFinish,
+	Graphics.Rendering.OGL.GL.Fog,
+	Graphics.Rendering.OGL.GL.Framebuffer,
+	Graphics.Rendering.OGL.GL.Hints,
+	Graphics.Rendering.OGL.GL,
+	Graphics.Rendering.OGL.GL.LineSegments,
+	Graphics.Rendering.OGL.GL.PerFragment,
+	Graphics.Rendering.OGL.GL.PixelRectangles.ColorTable,
+	Graphics.Rendering.OGL.GL.PixelRectangles.Convolution,
+	Graphics.Rendering.OGL.GL.PixelRectangles.Histogram,
+	Graphics.Rendering.OGL.GL.PixelRectangles,
+	Graphics.Rendering.OGL.GL.PixelRectangles.Minmax,
+	Graphics.Rendering.OGL.GL.PixelRectangles.PixelMap,
+	Graphics.Rendering.OGL.GL.PixelRectangles.PixelStorage,
+	Graphics.Rendering.OGL.GL.PixelRectangles.PixelTransfer,
+	Graphics.Rendering.OGL.GL.PixelRectangles.Rasterization,
+	Graphics.Rendering.OGL.GL.Points,
+	Graphics.Rendering.OGL.GL.Polygons,
+	Graphics.Rendering.OGL.GL.RasterPos,
+	Graphics.Rendering.OGL.GL.ReadCopyPixels,
+	Graphics.Rendering.OGL.GL.Rectangles,
+	Graphics.Rendering.OGL.GL.SavingState,
+	Graphics.Rendering.OGL.GL.Selection,
+	Graphics.Rendering.OGL.GL.Shaders,
+	Graphics.Rendering.OGL.GL.StateVar,
+	Graphics.Rendering.OGL.GL.StringQueries,
+	Graphics.Rendering.OGL.GL.Texturing.Application,
+	Graphics.Rendering.OGL.GL.Texturing.Environments,
+	Graphics.Rendering.OGL.GL.Texturing,
+	Graphics.Rendering.OGL.GL.Texturing.Objects,
+	Graphics.Rendering.OGL.GL.Texturing.Parameters,
+	Graphics.Rendering.OGL.GL.Texturing.Queries,
+	Graphics.Rendering.OGL.GL.Texturing.Specification,
+	Graphics.Rendering.OGL.GLU.Errors,
+	Graphics.Rendering.OGL.GLU,
+	Graphics.Rendering.OGL.GLU.Initialization,
+	Graphics.Rendering.OGL.GLU.Matrix,
+	Graphics.Rendering.OGL.GLU.Mipmapping,
+	Graphics.Rendering.OGL.GLU.NURBS,
+	Graphics.Rendering.OGL.GLU.Quadrics,
+	Graphics.Rendering.OGL.GLU.Tessellation,
+	Graphics.Rendering.OGL.GL.VertexArrays,
+	Graphics.Rendering.OGL.GL.VertexSpec,
+	Graphics.Rendering.OGL
+other-modules:
+	Graphics.Rendering.OGL.GL.BlendingFactor,
+	Graphics.Rendering.OGL.GL.BufferMode,
+	Graphics.Rendering.OGL.GL.Capability,
+	Graphics.Rendering.OGL.GL.ComparisonFunction,
+	Graphics.Rendering.OGL.GL.ControlPoint,
+	Graphics.Rendering.OGL.GL.DataType,
+	Graphics.Rendering.OGL.GL.Domain,
+	Graphics.Rendering.OGL.GL.EdgeFlag,
+	Graphics.Rendering.OGL.GL.Exception,
+	Graphics.Rendering.OGL.GL.Extensions,
+	Graphics.Rendering.OGL.GL.Face,
+	Graphics.Rendering.OGL.GL.GLboolean,
+	Graphics.Rendering.OGL.GL.IOState,
+	Graphics.Rendering.OGL.GL.PeekPoke,
+	Graphics.Rendering.OGL.GL.PixelData,
+	Graphics.Rendering.OGL.GL.PixelFormat,
+	Graphics.Rendering.OGL.GL.PixelRectangles.Reset,
+	Graphics.Rendering.OGL.GL.PixelRectangles.Sink,
+	Graphics.Rendering.OGL.GL.PointParameter,
+	Graphics.Rendering.OGL.GL.PolygonMode,
+	Graphics.Rendering.OGL.GL.PrimitiveMode,
+	Graphics.Rendering.OGL.GL.QueryUtils,
+	Graphics.Rendering.OGL.GL.RenderMode,
+	Graphics.Rendering.OGL.GL.Texturing.PixelInternalFormat,
+	Graphics.Rendering.OGL.GL.Texturing.TexParameter,
+	Graphics.Rendering.OGL.GL.Texturing.TextureTarget,
+	Graphics.Rendering.OGL.GL.Texturing.TextureUnit,
+	Graphics.Rendering.OGL.GLU.ErrorsInternal
+c-sources:	cbits/HsOpenGL.c
+include-dirs:	include
+includes: HsOpenGL.h
+install-includes: HsOpenGL.h
+build-depends:	base, mtl
+extensions:	CPP, ForeignFunctionInterface, GeneralizedNewtypeDeriving
diff --git a/OpenGL.buildinfo.in b/OpenGL.buildinfo.in
new file mode 100644
--- /dev/null
+++ b/OpenGL.buildinfo.in
@@ -0,0 +1,8 @@
+-- @configure_input@
+-- System-dependent values used by Distribution.Simple.defaultUserHooks
+--
+buildable: @BUILD_PACKAGE_BOOL@
+ghc-options: -DCALLCONV=@CALLCONV@
+cc-options: -DCALLCONV=@CALLCONV@ @GLU_CFLAGS@
+ld-options: @GLU_LIBS@
+frameworks: @GLU_FRAMEWORKS@
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,6 @@
+module Main (main) where
+
+import Distribution.Simple
+
+main :: IO ()
+main = defaultMainWithHooks defaultUserHooks
diff --git a/cbits/HsOpenGL.c b/cbits/HsOpenGL.c
new file mode 100644
--- /dev/null
+++ b/cbits/HsOpenGL.c
@@ -0,0 +1,125 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Module      :  C support for Graphics.Rendering.OGL.GL.Extensions
+ * Copyright   :  (c) Sven Panne 2002-2005
+ * License     :  BSD-style (see the file libraries/GLUT/LICENSE)
+ * 
+ * Maintainer  :  sven.panne@aedion.de
+ * Stability   :  experimental
+ * Portability :  portable
+ *
+ * -------------------------------------------------------------------------- */
+
+#include "HsOpenGL.h"
+#include <string.h>
+
+#if defined(_WIN32)
+#define hs_OpenGL_gpa(x) wglGetProcAddress((LPCSTR)(x))
+#elif defined(USE_QUARTZ_OPENGL)
+#include <mach-o/dyld.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static void*
+hs_OpenGL_gpa(const char *name)
+{
+  NSSymbol symbol;
+
+  /* Prepend a '_' for the Unix C symbol mangling convention */
+  char* symbolName = (char*)malloc(strlen(name) + 2);
+  if (!symbolName) {
+    fprintf(stderr, "Failed to allocate memory for NSGLGetProcAddress\n");
+    return NULL;
+  }
+  symbolName[0] = '_';
+  strcpy(symbolName + 1, name);
+
+  if (!NSIsSymbolNameDefined(symbolName)) {
+    free(symbolName);
+    return NULL;
+  }
+
+  symbol = NSLookupAndBindSymbol(symbolName);
+  free(symbolName);
+  if (!symbol) {
+    return NULL;
+  }
+
+  return NSAddressOfSymbol(symbol);
+}
+
+/* ToDo: This should really be based on a feature test. */
+#elif defined(__sgi) || defined (__sun)
+#include <dlfcn.h>
+
+static const char* gpaNames[] = {
+  "glXGetProcAddress", "glXGetProcAddressARB", "glXGetProcAddressEXT",
+  "_glXGetProcAddress", "_glXGetProcAddressARB", "_glXGetProcAddressEXT"
+};
+
+static void*
+hs_OpenGL_gpa(const char *name)
+{
+  static int firstTime = 1;
+  static void *handle = NULL;
+  static void *gpa = NULL;
+
+  if (firstTime) {
+    firstTime = 0;
+
+    /* Get a handle for our executable. */
+    handle = dlopen(NULL, RTLD_LAZY);
+    /* If fail this early, there's not much we can do about it. */
+    if (!handle) {
+      return NULL;
+    }
+
+    {
+      /* Let's see if our platform supports a glXGetProcAddress() variant. */
+      int numNames = (int)(sizeof(gpaNames) / sizeof(gpaNames[0]));
+      int i;
+      for (i = 0;   (!gpa) && (i < numNames);   ++i) {
+        gpa = dlsym(handle, gpaNames[i]);
+      }
+    }
+  }
+
+  if (gpa) {
+    /* Fine, we seem to have some kind of glXGetProcAddress(), so use it. */
+    return ((void *(*)(const GLubyte *))gpa)(name);
+  } else if (handle) {
+    /* Fallback to dlsym() if we have no glXGetProcAddress(), although we then
+       ignore the fact that OpenGL entry points could be context dependent. */
+    return dlsym(handle, name);
+  } else {
+    return NULL;
+  }
+}
+
+#else
+#define hs_OpenGL_gpa(x) glXGetProcAddressARB((const GLubyte*)(x))
+#endif
+
+
+/* procName is really a const char*, but currently we can't specify this in
+   Haskell's FFI and consequently get a warning from the C compiler. */
+void*
+hs_OpenGL_getProcAddress(char *procName)
+{
+  void* addr = hs_OpenGL_gpa(procName);
+  if (addr) {
+    return addr;
+  }
+  /* There is no way to get GLU extensions at runtime so we fake this, being
+     careful about GLU headers on WinDoze, which have a bad habit of lying
+     about their actual version. */
+#if defined(GLU_VERSION_1_3) && !defined(_WIN32)
+  if (strcmp(procName, "gluUnProject4") == 0) {
+    return gluUnProject4;
+  }
+  if (strcmp(procName, "gluBuild3DMipmapLevels") == 0) {
+    return gluBuild3DMipmapLevels;
+  }
+#endif
+  return NULL;
+}
diff --git a/config.guess b/config.guess
new file mode 100644
--- /dev/null
+++ b/config.guess
@@ -0,0 +1,1497 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2006-02-23'
+
+# This file 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.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	case ${UNAME_MACHINE} in
+	    pc98)
+		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:MSYS_NT-*:*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    x86:Interix*:[345]*)
+	echo i586-pc-interix${UNAME_RELEASE}
+	exit ;;
+    EM64T:Interix*:[345]*)
+	echo x86_64-unknown-interix${UNAME_RELEASE}
+	exit ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun)
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^LIBC/{
+		s: ::g
+		p
+	    }'`"
+	test x"${LIBC}" != x && {
+		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+		exit
+	}
+	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.mk.in b/config.mk.in
new file mode 100644
--- /dev/null
+++ b/config.mk.in
@@ -0,0 +1,9 @@
+GL_BUILD_PACKAGE=@GL_BUILD_PACKAGE@
+ifneq "$(GL_BUILD_PACKAGE)" "no"
+GLU_LIBS=@GLU_LIBS@
+GLU_CFLAGS=@GLU_CFLAGS@
+GLU_FRAMEWORKS=@GLU_FRAMEWORKS@
+PACKAGE=@PACKAGE_TARNAME@
+VERSION=@PACKAGE_VERSION@
+MAINTAINER=@PACKAGE_BUGREPORT@
+endif
diff --git a/config.sub b/config.sub
new file mode 100644
--- /dev/null
+++ b/config.sub
@@ -0,0 +1,1608 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2006-02-23'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| mt \
+	| msp430 \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m32c)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	m32c-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16c)
+		basic_machine=cr16c-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/configure b/configure
new file mode 100644
--- /dev/null
+++ b/configure
@@ -0,0 +1,9178 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.61 for Haskell OpenGL package 2.2.1.
+#
+# Report bugs to <sven.panne@aedion.de>.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+  if (eval ":") 2>/dev/null; then
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+
+  if test $as_have_required = yes && 	 (eval ":
+(as_func_return () {
+  (exit \$1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+  as_lineno_1=\$LINENO
+  as_lineno_2=\$LINENO
+  test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+  test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+  :
+else
+  as_candidate_shells=
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  case $as_dir in
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+	   done;;
+       esac
+done
+IFS=$as_save_IFS
+
+
+      for as_shell in $as_candidate_shells $SHELL; do
+	 # Try only shells that exist, to save several forks.
+	 if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		{ ("$as_shell") 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+_ASEOF
+}; then
+  CONFIG_SHELL=$as_shell
+	       as_have_required=yes
+	       if { "$as_shell" 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+(as_func_return () {
+  (exit $1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+  break
+fi
+
+fi
+
+      done
+
+      if test "x$CONFIG_SHELL" != x; then
+  for as_var in BASH_ENV ENV
+        do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+        done
+        export CONFIG_SHELL
+        exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+    if test $as_have_required = no; then
+  echo This script requires a shell more modern than all the
+      echo shells that I found on your system.  Please install a
+      echo modern shell, or manually run the script under such a
+      echo shell if you do have one.
+      { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+  (exit \$1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+  echo No shell found that supports shell functions.
+  echo Please tell autoconf@gnu.org about your system,
+  echo including any error possibly output before this
+  echo message
+}
+
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line after each line using $LINENO; the second 'sed'
+  # does the real work.  The second script uses 'N' to pair each
+  # line-number line with the line containing $LINENO, and appends
+  # trailing '-' during substitution so that $LINENO is not a special
+  # case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # scripts with optimization help from Paolo Bonzini.  Blame Lee
+  # E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+  case `echo 'x\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  *)   ECHO_C='\c';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s='ln -s'
+  # ... but there are two gotchas:
+  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+  # In both cases, we have to default to `cp -p'.
+  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+    as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+        test -d "$1/.";
+      else
+	case $1 in
+        -*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME='Haskell OpenGL package'
+PACKAGE_TARNAME='OpenGL'
+PACKAGE_VERSION='2.2.1'
+PACKAGE_STRING='Haskell OpenGL package 2.2.1'
+PACKAGE_BUGREPORT='sven.panne@aedion.de'
+
+ac_unique_file="include/HsOpenGL.h.in"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL
+PATH_SEPARATOR
+PACKAGE_NAME
+PACKAGE_TARNAME
+PACKAGE_VERSION
+PACKAGE_STRING
+PACKAGE_BUGREPORT
+exec_prefix
+prefix
+program_transform_name
+bindir
+sbindir
+libexecdir
+datarootdir
+datadir
+sysconfdir
+sharedstatedir
+localstatedir
+includedir
+oldincludedir
+docdir
+infodir
+htmldir
+dvidir
+pdfdir
+psdir
+libdir
+localedir
+mandir
+DEFS
+ECHO_C
+ECHO_N
+ECHO_T
+LIBS
+build_alias
+host_alias
+target_alias
+GL_BUILD_PACKAGE
+CC
+CFLAGS
+LDFLAGS
+CPPFLAGS
+ac_ct_CC
+EXEEXT
+OBJEXT
+XMKMF
+CPP
+X_CFLAGS
+X_PRE_LIBS
+X_LIBS
+X_EXTRA_LIBS
+build
+build_cpu
+build_vendor
+build_os
+host
+host_cpu
+host_vendor
+host_os
+target
+target_cpu
+target_vendor
+target_os
+GLU_FRAMEWORKS
+GLUT_FRAMEWORKS
+GL_CFLAGS
+GL_LIBS
+GLU_CFLAGS
+GLU_LIBS
+GREP
+EGREP
+BUILD_PACKAGE_BOOL
+CALLCONV
+LIBOBJS
+LTLIBOBJS'
+ac_subst_files=''
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+XMKMF
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *)	ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
+    eval enable_$ac_feature=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
+    eval enable_$ac_feature=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
+    eval with_$ac_package=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
+    eval with_$ac_package=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute directory names.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; }
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  { echo "$as_me: error: Working directory cannot be determined" >&2
+   { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  { echo "$as_me: error: pwd does not report name of working directory" >&2
+   { (exit 1); exit 1; }; }
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$0" ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
+   { (exit 1); exit 1; }; }
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures Haskell OpenGL package 2.2.1 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --datarootdir=DIR      read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR          read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR          info documentation [DATAROOTDIR/info]
+  --localedir=DIR        locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR           man documentation [DATAROOTDIR/man]
+  --docdir=DIR           documentation root [DATAROOTDIR/doc/OpenGL]
+  --htmldir=DIR          html documentation [DOCDIR]
+  --dvidir=DIR           dvi documentation [DOCDIR]
+  --pdfdir=DIR           pdf documentation [DOCDIR]
+  --psdir=DIR            ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+X features:
+  --x-includes=DIR    X include files are in DIR
+  --x-libraries=DIR   X library files are in DIR
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of Haskell OpenGL package 2.2.1:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-opengl         build a Haskell binding for OpenGL (GL/GLU). On Mac
+                          OS X, use --enable-opengl=x11 to use X11 instead of
+                          the "native" libraries. (default=autodetect)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-x                use the X Window System
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  XMKMF       Path to xmkmf, Makefile generator for X Window System
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <sven.panne@aedion.de>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" || continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+Haskell OpenGL package configure 2.2.1
+generated by GNU Autoconf 2.61
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by Haskell OpenGL package $as_me 2.2.1, which was
+generated by GNU Autoconf 2.61.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args '$ac_arg'"
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      *) $as_unset $ac_var ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -n "$CONFIG_SITE"; then
+  set x "$CONFIG_SITE"
+elif test "x$prefix" != xNONE; then
+  set x "$prefix/share/config.site" "$prefix/etc/config.site"
+else
+  set x "$ac_default_prefix/share/config.site" \
+	"$ac_default_prefix/etc/config.site"
+fi
+shift
+for ac_site_file
+do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# Safety check: Ensure that we are in the correct source directory.
+
+
+# The first file mentioned below will be generated by autoheader and contains
+# defines which are needed during package build time only. The second header
+# contains all kinds of stuff which is needed for using this package.
+ac_config_headers="$ac_config_headers include/HsOpenGLConfig.h include/HsOpenGL.h"
+
+
+# We set this to "yes" later when we have found OpenGL libs and headers.
+GL_BUILD_PACKAGE=no
+
+
+# Shall we build this package at all?
+# Check whether --enable-opengl was given.
+if test "${enable_opengl+set}" = set; then
+  enableval=$enable_opengl; enable_opengl=$enableval
+else
+  enable_opengl=yes
+fi
+
+
+
+if test x"$enable_opengl" != xno; then
+
+# Check for OpenGL include paths and libraries
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler --version >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -v >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -V >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+#
+# List of possible output files, starting from the most likely.
+# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
+# only as a last resort.  b.out is created by i960 compilers.
+ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
+#
+# The IRIX 6 linker writes into existing files which may not be
+# executable, retaining their permissions.  Remove them first so a
+# subsequent execution test works.
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { (ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+        if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+
+{ echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6; }
+if test -z "$ac_file"; then
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; }
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+{ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6; }
+
+{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	CFLAGS=""
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_prog_cc_c89=$ac_arg
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6; } ;;
+  xno)
+    { echo "$as_me:$LINENO: result: unsupported" >&5
+echo "${ECHO_T}unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ echo "$as_me:$LINENO: checking for Windows environment" >&5
+echo $ECHO_N "checking for Windows environment... $ECHO_C" >&6; }
+if test "${fp_cv_is_win32+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#if !_WIN32
+   syntax error;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  fp_cv_is_win32=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	fp_cv_is_win32=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $fp_cv_is_win32" >&5
+echo "${ECHO_T}$fp_cv_is_win32" >&6; }
+fp_is_win32="$fp_cv_is_win32"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ echo "$as_me:$LINENO: checking for X" >&5
+echo $ECHO_N "checking for X... $ECHO_C" >&6; }
+
+
+# Check whether --with-x was given.
+if test "${with_x+set}" = set; then
+  withval=$with_x;
+fi
+
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+  # The user explicitly disabled X.
+  have_x=disabled
+else
+  case $x_includes,$x_libraries in #(
+    *\'*) { { echo "$as_me:$LINENO: error: Cannot use X directory names containing '" >&5
+echo "$as_me: error: Cannot use X directory names containing '" >&2;}
+   { (exit 1); exit 1; }; };; #(
+    *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=no ac_x_libraries=no
+rm -f -r conftest.dir
+if mkdir conftest.dir; then
+  cd conftest.dir
+  cat >Imakefile <<'_ACEOF'
+incroot:
+	@echo incroot='${INCROOT}'
+usrlibdir:
+	@echo usrlibdir='${USRLIBDIR}'
+libdir:
+	@echo libdir='${LIBDIR}'
+_ACEOF
+  if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then
+    # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+    for ac_var in incroot usrlibdir libdir; do
+      eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`"
+    done
+    # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+    for ac_extension in a so sl; do
+      if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" &&
+	 test -f "$ac_im_libdir/libX11.$ac_extension"; then
+	ac_im_usrlibdir=$ac_im_libdir; break
+      fi
+    done
+    # Screen out bogus values from the imake configuration.  They are
+    # bogus both because they are the default anyway, and because
+    # using them would break gcc on systems where it needs fixed includes.
+    case $ac_im_incroot in
+	/usr/include) ac_x_includes= ;;
+	*) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;;
+    esac
+    case $ac_im_usrlibdir in
+	/usr/lib | /lib) ;;
+	*) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;;
+    esac
+  fi
+  cd ..
+  rm -f -r conftest.dir
+fi
+
+# Standard set of common directories for X headers.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ac_x_header_dirs='
+/usr/X11/include
+/usr/X11R6/include
+/usr/X11R5/include
+/usr/X11R4/include
+
+/usr/include/X11
+/usr/include/X11R6
+/usr/include/X11R5
+/usr/include/X11R4
+
+/usr/local/X11/include
+/usr/local/X11R6/include
+/usr/local/X11R5/include
+/usr/local/X11R4/include
+
+/usr/local/include/X11
+/usr/local/include/X11R6
+/usr/local/include/X11R5
+/usr/local/include/X11R4
+
+/usr/X386/include
+/usr/x386/include
+/usr/XFree86/include/X11
+
+/usr/include
+/usr/local/include
+/usr/unsupported/include
+/usr/athena/include
+/usr/local/x11r5/include
+/usr/lpp/Xamples/include
+
+/usr/openwin/include
+/usr/openwin/share/include'
+
+if test "$ac_x_includes" = no; then
+  # Guess where to find include files, by looking for Xlib.h.
+  # First, try using that file with no special directory specified.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  for ac_dir in $ac_x_header_dirs; do
+  if test -r "$ac_dir/X11/Xlib.h"; then
+    ac_x_includes=$ac_dir
+    break
+  fi
+done
+fi
+
+rm -f conftest.err conftest.$ac_ext
+fi # $ac_x_includes = no
+
+if test "$ac_x_libraries" = no; then
+  # Check for the libraries.
+  # See if we find them without any special options.
+  # Don't add to $LIBS permanently.
+  ac_save_LIBS=$LIBS
+  LIBS="-lX11 $LIBS"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+int
+main ()
+{
+XrmInitialize ()
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  LIBS=$ac_save_LIBS
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	LIBS=$ac_save_LIBS
+for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g`
+do
+  # Don't even attempt the hair of trying to link an X program!
+  for ac_extension in a so sl; do
+    if test -r "$ac_dir/libX11.$ac_extension"; then
+      ac_x_libraries=$ac_dir
+      break 2
+    fi
+  done
+done
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi # $ac_x_libraries = no
+
+case $ac_x_includes,$ac_x_libraries in #(
+  no,* | *,no | *\'*)
+    # Didn't find X, or a directory has "'" in its name.
+    ac_cv_have_x="have_x=no";; #(
+  *)
+    # Record where we found X for the cache.
+    ac_cv_have_x="have_x=yes\
+	ac_x_includes='$ac_x_includes'\
+	ac_x_libraries='$ac_x_libraries'"
+esac
+fi
+;; #(
+    *) have_x=yes;;
+  esac
+  eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+  { echo "$as_me:$LINENO: result: $have_x" >&5
+echo "${ECHO_T}$have_x" >&6; }
+  no_x=yes
+else
+  # If each of the values was on the command line, it overrides each guess.
+  test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+  test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+  # Update the cache value to reflect the command line values.
+  ac_cv_have_x="have_x=yes\
+	ac_x_includes='$x_includes'\
+	ac_x_libraries='$x_libraries'"
+  { echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5
+echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6; }
+fi
+
+
+if test x"$fp_is_win32" = xyes; then
+  no_x=yes
+else
+  if test "$no_x" = yes; then
+  # Not all programs may use this symbol, but it does not hurt to define it.
+
+cat >>confdefs.h <<\_ACEOF
+#define X_DISPLAY_MISSING 1
+_ACEOF
+
+  X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS=
+else
+  if test -n "$x_includes"; then
+    X_CFLAGS="$X_CFLAGS -I$x_includes"
+  fi
+
+  # It would also be nice to do this for all -L options, not just this one.
+  if test -n "$x_libraries"; then
+    X_LIBS="$X_LIBS -L$x_libraries"
+    # For Solaris; some versions of Sun CC require a space after -R and
+    # others require no space.  Words are not sufficient . . . .
+    { echo "$as_me:$LINENO: checking whether -R must be followed by a space" >&5
+echo $ECHO_N "checking whether -R must be followed by a space... $ECHO_C" >&6; }
+    ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries"
+    ac_xsave_c_werror_flag=$ac_c_werror_flag
+    ac_c_werror_flag=yes
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+       X_LIBS="$X_LIBS -R$x_libraries"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	LIBS="$ac_xsave_LIBS -R $x_libraries"
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+	  X_LIBS="$X_LIBS -R $x_libraries"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	{ echo "$as_me:$LINENO: result: neither works" >&5
+echo "${ECHO_T}neither works" >&6; }
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+    ac_c_werror_flag=$ac_xsave_c_werror_flag
+    LIBS=$ac_xsave_LIBS
+  fi
+
+  # Check for system-dependent libraries X programs must link with.
+  # Do this before checking for the system-independent R6 libraries
+  # (-lICE), since we may need -lsocket or whatever for X linking.
+
+  if test "$ISC" = yes; then
+    X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet"
+  else
+    # Martyn Johnson says this is needed for Ultrix, if the X
+    # libraries were built with DECnet support.  And Karl Berry says
+    # the Alpha needs dnet_stub (dnet does not exist).
+    ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XOpenDisplay ();
+int
+main ()
+{
+return XOpenDisplay ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	{ echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet" >&5
+echo $ECHO_N "checking for dnet_ntoa in -ldnet... $ECHO_C" >&6; }
+if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldnet  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dnet_ntoa ();
+int
+main ()
+{
+return dnet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_dnet_dnet_ntoa=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_dnet_dnet_ntoa=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_dnet_ntoa" >&5
+echo "${ECHO_T}$ac_cv_lib_dnet_dnet_ntoa" >&6; }
+if test $ac_cv_lib_dnet_dnet_ntoa = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
+fi
+
+    if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+      { echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet_stub" >&5
+echo $ECHO_N "checking for dnet_ntoa in -ldnet_stub... $ECHO_C" >&6; }
+if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldnet_stub  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dnet_ntoa ();
+int
+main ()
+{
+return dnet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_dnet_stub_dnet_ntoa=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_dnet_stub_dnet_ntoa=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5
+echo "${ECHO_T}$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; }
+if test $ac_cv_lib_dnet_stub_dnet_ntoa = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
+fi
+
+    fi
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+    LIBS="$ac_xsave_LIBS"
+
+    # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+    # to get the SysV transport functions.
+    # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4)
+    # needs -lnsl.
+    # The nsl library prevents programs from opening the X display
+    # on Irix 5.2, according to T.E. Dickey.
+    # The functions gethostbyname, getservbyname, and inet_addr are
+    # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking.
+    { echo "$as_me:$LINENO: checking for gethostbyname" >&5
+echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6; }
+if test "${ac_cv_func_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define gethostbyname to an innocuous variant, in case <limits.h> declares gethostbyname.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define gethostbyname innocuous_gethostbyname
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char gethostbyname (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef gethostbyname
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_gethostbyname || defined __stub___gethostbyname
+choke me
+#endif
+
+int
+main ()
+{
+return gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_func_gethostbyname=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6; }
+
+    if test $ac_cv_func_gethostbyname = no; then
+      { echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
+echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_nsl_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_nsl_gethostbyname=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6; }
+if test $ac_cv_lib_nsl_gethostbyname = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
+fi
+
+      if test $ac_cv_lib_nsl_gethostbyname = no; then
+	{ echo "$as_me:$LINENO: checking for gethostbyname in -lbsd" >&5
+echo $ECHO_N "checking for gethostbyname in -lbsd... $ECHO_C" >&6; }
+if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbsd  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_bsd_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_bsd_gethostbyname=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_bsd_gethostbyname" >&6; }
+if test $ac_cv_lib_bsd_gethostbyname = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd"
+fi
+
+      fi
+    fi
+
+    # lieder@skyler.mavd.honeywell.com says without -lsocket,
+    # socket/setsockopt and other routines are undefined under SCO ODT
+    # 2.0.  But -lsocket is broken on IRIX 5.2 (and is not necessary
+    # on later versions), says Simon Leinen: it contains gethostby*
+    # variants that don't use the name server (or something).  -lsocket
+    # must be given before -lnsl if both are needed.  We assume that
+    # if connect needs -lnsl, so does gethostbyname.
+    { echo "$as_me:$LINENO: checking for connect" >&5
+echo $ECHO_N "checking for connect... $ECHO_C" >&6; }
+if test "${ac_cv_func_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define connect to an innocuous variant, in case <limits.h> declares connect.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define connect innocuous_connect
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char connect (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef connect
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char connect ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_connect || defined __stub___connect
+choke me
+#endif
+
+int
+main ()
+{
+return connect ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_func_connect=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5
+echo "${ECHO_T}$ac_cv_func_connect" >&6; }
+
+    if test $ac_cv_func_connect = no; then
+      { echo "$as_me:$LINENO: checking for connect in -lsocket" >&5
+echo $ECHO_N "checking for connect in -lsocket... $ECHO_C" >&6; }
+if test "${ac_cv_lib_socket_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char connect ();
+int
+main ()
+{
+return connect ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_socket_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_socket_connect=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_connect" >&6; }
+if test $ac_cv_lib_socket_connect = yes; then
+  X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
+fi
+
+    fi
+
+    # Guillermo Gomez says -lposix is necessary on A/UX.
+    { echo "$as_me:$LINENO: checking for remove" >&5
+echo $ECHO_N "checking for remove... $ECHO_C" >&6; }
+if test "${ac_cv_func_remove+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define remove to an innocuous variant, in case <limits.h> declares remove.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define remove innocuous_remove
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char remove (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef remove
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char remove ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_remove || defined __stub___remove
+choke me
+#endif
+
+int
+main ()
+{
+return remove ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_remove=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_func_remove=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_remove" >&5
+echo "${ECHO_T}$ac_cv_func_remove" >&6; }
+
+    if test $ac_cv_func_remove = no; then
+      { echo "$as_me:$LINENO: checking for remove in -lposix" >&5
+echo $ECHO_N "checking for remove in -lposix... $ECHO_C" >&6; }
+if test "${ac_cv_lib_posix_remove+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lposix  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char remove ();
+int
+main ()
+{
+return remove ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_posix_remove=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_posix_remove=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_posix_remove" >&5
+echo "${ECHO_T}$ac_cv_lib_posix_remove" >&6; }
+if test $ac_cv_lib_posix_remove = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
+fi
+
+    fi
+
+    # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+    { echo "$as_me:$LINENO: checking for shmat" >&5
+echo $ECHO_N "checking for shmat... $ECHO_C" >&6; }
+if test "${ac_cv_func_shmat+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define shmat to an innocuous variant, in case <limits.h> declares shmat.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define shmat innocuous_shmat
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shmat (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef shmat
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shmat ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_shmat || defined __stub___shmat
+choke me
+#endif
+
+int
+main ()
+{
+return shmat ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_shmat=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_func_shmat=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_shmat" >&5
+echo "${ECHO_T}$ac_cv_func_shmat" >&6; }
+
+    if test $ac_cv_func_shmat = no; then
+      { echo "$as_me:$LINENO: checking for shmat in -lipc" >&5
+echo $ECHO_N "checking for shmat in -lipc... $ECHO_C" >&6; }
+if test "${ac_cv_lib_ipc_shmat+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lipc  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shmat ();
+int
+main ()
+{
+return shmat ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_ipc_shmat=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_ipc_shmat=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_ipc_shmat" >&5
+echo "${ECHO_T}$ac_cv_lib_ipc_shmat" >&6; }
+if test $ac_cv_lib_ipc_shmat = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
+fi
+
+    fi
+  fi
+
+  # Check for libraries that X11R6 Xt/Xaw programs need.
+  ac_save_LDFLAGS=$LDFLAGS
+  test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries"
+  # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
+  # check for ICE first), but we must link in the order -lSM -lICE or
+  # we get undefined symbols.  So assume we have SM if we have ICE.
+  # These have to be linked with before -lX11, unlike the other
+  # libraries we check for below, so use a different variable.
+  # John Interrante, Karl Berry
+  { echo "$as_me:$LINENO: checking for IceConnectionNumber in -lICE" >&5
+echo $ECHO_N "checking for IceConnectionNumber in -lICE... $ECHO_C" >&6; }
+if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lICE $X_EXTRA_LIBS $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char IceConnectionNumber ();
+int
+main ()
+{
+return IceConnectionNumber ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_ICE_IceConnectionNumber=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_ICE_IceConnectionNumber=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5
+echo "${ECHO_T}$ac_cv_lib_ICE_IceConnectionNumber" >&6; }
+if test $ac_cv_lib_ICE_IceConnectionNumber = yes; then
+  X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
+fi
+
+  LDFLAGS=$ac_save_LDFLAGS
+
+fi
+
+fi
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
+echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+{ echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6; }
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5
+echo "$as_me: error: invalid value of canonical build" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6; }
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5
+echo "$as_me: error: invalid value of canonical host" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+{ echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6; }
+if test "${ac_cv_target+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "x$target_alias" = x; then
+  ac_cv_target=$ac_cv_host
+else
+  ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
+    { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6; }
+case $ac_cv_target in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5
+echo "$as_me: error: invalid value of canonical target" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
+target=$ac_cv_target
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_target
+shift
+target_cpu=$1
+target_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+target_os=$*
+IFS=$ac_save_IFS
+case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+
+
+use_quartz_opengl=no
+if test x"$enable_opengl" = xyes; then
+  case $target_os in
+  darwin*)
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_QUARTZ_OPENGL 1
+_ACEOF
+
+    use_quartz_opengl=yes
+    ;;
+  esac
+fi
+
+GLU_FRAMEWORKS=
+GLUT_FRAMEWORKS=
+if test x"$use_quartz_opengl" = xyes; then
+  GLU_FRAMEWORKS=OpenGL
+  GLUT_FRAMEWORKS=GLUT
+fi
+
+
+
+
+
+
+
+if test x"$use_quartz_opengl" = xno; then
+  { echo "$as_me:$LINENO: checking for atan" >&5
+echo $ECHO_N "checking for atan... $ECHO_C" >&6; }
+if test "${ac_cv_func_atan+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define atan to an innocuous variant, in case <limits.h> declares atan.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define atan innocuous_atan
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char atan (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef atan
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char atan ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_atan || defined __stub___atan
+choke me
+#endif
+
+int
+main ()
+{
+return atan ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_atan=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_func_atan=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_atan" >&5
+echo "${ECHO_T}$ac_cv_func_atan" >&6; }
+if test $ac_cv_func_atan = yes; then
+  fp_libm_not_needed=yes
+else
+  fp_libm_not_needed=dunno
+fi
+
+  if test x"$fp_libm_not_needed" = xdunno; then
+     { echo "$as_me:$LINENO: checking for atan in -lm" >&5
+echo $ECHO_N "checking for atan in -lm... $ECHO_C" >&6; }
+if test "${ac_cv_lib_m_atan+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char atan ();
+int
+main ()
+{
+return atan ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_m_atan=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_m_atan=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_m_atan" >&5
+echo "${ECHO_T}$ac_cv_lib_m_atan" >&6; }
+if test $ac_cv_lib_m_atan = yes; then
+  GL_LIBS="-lm $GL_LIBS"
+fi
+
+  fi
+
+  if test x"$no_x" != xyes; then
+    test -n "$x_includes" && GL_CFLAGS="-I$x_includes $GL_CFLAGS"
+    test -n "$x_libraries" && GL_LIBS="-L$x_libraries -lX11 $GL_LIBS"
+  fi
+
+  { echo "$as_me:$LINENO: checking for GL library" >&5
+echo $ECHO_N "checking for GL library... $ECHO_C" >&6; }
+if test "${fp_cv_check_GL_lib+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fp_cv_check_GL_lib="no"
+  fp_save_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS ${GL_CFLAGS}"
+  fp_save_LIBS="$LIBS"
+  for fp_try_lib in -lGL -lopengl32; do
+    # transform "-lfoo" to "foo.lib" when using cl
+    if test x"$CC" = xcl; then
+      fp_try_lib=`echo $fp_try_lib | sed -e 's/^-l//' -e 's/$/.lib/'`
+    fi
+    LIBS="$fp_try_lib ${GL_LIBS} $fp_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <GL/gl.h>
+int
+main ()
+{
+glEnd()
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  fp_cv_check_GL_lib="$fp_try_lib ${GL_LIBS}"; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+  LIBS="$fp_save_LIBS"
+  CPPFLAGS="$fp_save_CPPFLAGS"
+fi
+{ echo "$as_me:$LINENO: result: $fp_cv_check_GL_lib" >&5
+echo "${ECHO_T}$fp_cv_check_GL_lib" >&6; }
+
+  if test x"$fp_cv_check_GL_lib" = xno; then
+    no_GL=yes
+    GL_CFLAGS=
+    GL_LIBS=
+  else
+    GL_CFLAGS0="${GL_CFLAGS}"
+    GL_CFLAGS="$CPPFLAGS ${GL_CFLAGS0}"
+    GL_LIBS0="$fp_cv_check_GL_lib"
+    GL_LIBS="$LDFLAGS ${GL_LIBS0}"
+  fi
+
+
+  if test x"$fp_is_win32" = xyes; then
+    # Ugly: To get wglGetProcAddress on Windows, we have to link with
+    # opengl32.dll, too, even when we are using Cygwin with X11.
+    case "$GL_LIBS" in
+      *-lopengl32*|*opengl32.lib*) ;;
+      *) fp_save_LIBS="$LIBS"
+         LIBS="$LIBS -lopengl32"
+         cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <GL/gl.h>
+int
+main ()
+{
+glEnd()
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  GL_LIBS="$GL_LIBS -lopengl32"; GL_LIBS0="$GL_LIBS0 -lopengl32"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+         LIBS="$fp_save_LIBS"
+         ;;
+    esac
+  fi
+fi
+
+
+
+GLU_CFLAGS="$GL_CFLAGS0"
+GLU_LIBS="$GL_LIBS0"
+
+if test x"$use_quartz_opengl" = xno; then
+  { echo "$as_me:$LINENO: checking for GLU library" >&5
+echo $ECHO_N "checking for GLU library... $ECHO_C" >&6; }
+if test "${fp_cv_check_GLU_lib+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fp_cv_check_GLU_lib="no"
+  fp_save_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS ${GLU_CFLAGS}"
+  fp_save_LIBS="$LIBS"
+  for fp_try_lib in -lglu32 -lGLU; do
+    # transform "-lfoo" to "foo.lib" when using cl
+    if test x"$CC" = xcl; then
+      fp_try_lib=`echo $fp_try_lib | sed -e 's/^-l//' -e 's/$/.lib/'`
+    fi
+    LIBS="$fp_try_lib ${GLU_LIBS} $fp_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <GL/glu.h>
+int
+main ()
+{
+gluNewQuadric()
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  fp_cv_check_GLU_lib="$fp_try_lib ${GLU_LIBS}"; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+  LIBS="$fp_save_LIBS"
+  CPPFLAGS="$fp_save_CPPFLAGS"
+fi
+{ echo "$as_me:$LINENO: result: $fp_cv_check_GLU_lib" >&5
+echo "${ECHO_T}$fp_cv_check_GLU_lib" >&6; }
+
+  if test x"$fp_cv_check_GLU_lib" = xno; then
+    no_GLU=yes
+    GLU_CFLAGS=
+    GLU_LIBS=
+  else
+    GLU_CFLAGS0="${GLU_CFLAGS}"
+    GLU_CFLAGS="$CPPFLAGS ${GLU_CFLAGS0}"
+    GLU_LIBS0="$fp_cv_check_GLU_lib"
+    GLU_LIBS="$LDFLAGS ${GLU_LIBS0}"
+  fi
+
+fi
+
+
+
+
+
+if test x"$GLU_LIBS" = xno; then
+  { { echo "$as_me:$LINENO: error: no OpenGL library found, so this package cannot be built
+See \`config.log' for more details." >&5
+echo "$as_me: error: no OpenGL library found, so this package cannot be built
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# check for OpenGL include files
+gl_found_header=no
+glu_found_header=no
+fp_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
+echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # Extract the first word of "grep ggrep" to use in msg output
+if test -z "$GREP"; then
+set dummy grep ggrep; ac_prog_name=$2
+if test "${ac_cv_path_GREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_path_GREP_found=false
+# Loop through the user's path and test for each of PROGNAME-LIST
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_prog in grep ggrep; do
+  for ac_exec_ext in '' $ac_executable_extensions; do
+    ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+    { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+    # Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    ac_count=`expr $ac_count + 1`
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+
+    $ac_path_GREP_found && break 3
+  done
+done
+
+done
+IFS=$as_save_IFS
+
+
+fi
+
+GREP="$ac_cv_path_GREP"
+if test -z "$GREP"; then
+  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
+echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     # Extract the first word of "egrep" to use in msg output
+if test -z "$EGREP"; then
+set dummy egrep; ac_prog_name=$2
+if test "${ac_cv_path_EGREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_path_EGREP_found=false
+# Loop through the user's path and test for each of PROGNAME-LIST
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_prog in egrep; do
+  for ac_exec_ext in '' $ac_executable_extensions; do
+    ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+    { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+    # Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    ac_count=`expr $ac_count + 1`
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+
+    $ac_path_EGREP_found && break 3
+  done
+done
+
+done
+IFS=$as_save_IFS
+
+
+fi
+
+EGREP="$ac_cv_path_EGREP"
+if test -z "$EGREP"; then
+  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+
+   fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
+echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_header_stdc=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+for ac_header in GL/gl.h OpenGL/gl.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    ( cat <<\_ASBOX
+## ----------------------------------- ##
+## Report this to sven.panne@aedion.de ##
+## ----------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ gl_found_header=yes
+fi
+
+done
+
+
+
+for ac_header in GL/glu.h OpenGL/glu.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    ( cat <<\_ASBOX
+## ----------------------------------- ##
+## Report this to sven.panne@aedion.de ##
+## ----------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ glu_found_header=yes
+fi
+
+done
+
+CPPFLAGS="$fp_save_cppflags"
+
+if test x"$gl_found_header" = xno || test x"$glu_found_header" = xno; then
+  { { echo "$as_me:$LINENO: error: no OpenGL headers found, so this package cannot be built
+See \`config.log' for more details." >&5
+echo "$as_me: error: no OpenGL headers found, so this package cannot be built
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+GL_BUILD_PACKAGE=yes
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLboolean" >&5
+echo $ECHO_N "checking Haskell type for GLboolean... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLboolean+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLboolean=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLboolean=NotReallyATypeCross; fptools_cv_htype_sup_GLboolean=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLboolean testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLboolean=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLboolean=NotReallyAType; fptools_cv_htype_sup_GLboolean=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLboolean" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLboolean" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLboolean" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLBOOLEAN $fptools_cv_htype_GLboolean
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLbyte" >&5
+echo $ECHO_N "checking Haskell type for GLbyte... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLbyte+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLbyte=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLbyte=NotReallyATypeCross; fptools_cv_htype_sup_GLbyte=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLbyte testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLbyte=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLbyte=NotReallyAType; fptools_cv_htype_sup_GLbyte=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLbyte" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLbyte" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLbyte" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLBYTE $fptools_cv_htype_GLbyte
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLubyte" >&5
+echo $ECHO_N "checking Haskell type for GLubyte... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLubyte+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLubyte=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLubyte=NotReallyATypeCross; fptools_cv_htype_sup_GLubyte=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLubyte testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLubyte=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLubyte=NotReallyAType; fptools_cv_htype_sup_GLubyte=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLubyte" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLubyte" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLubyte" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLUBYTE $fptools_cv_htype_GLubyte
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLshort" >&5
+echo $ECHO_N "checking Haskell type for GLshort... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLshort+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLshort=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLshort=NotReallyATypeCross; fptools_cv_htype_sup_GLshort=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLshort testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLshort=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLshort=NotReallyAType; fptools_cv_htype_sup_GLshort=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLshort" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLshort" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLshort" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLSHORT $fptools_cv_htype_GLshort
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLushort" >&5
+echo $ECHO_N "checking Haskell type for GLushort... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLushort+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLushort=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLushort=NotReallyATypeCross; fptools_cv_htype_sup_GLushort=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLushort testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLushort=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLushort=NotReallyAType; fptools_cv_htype_sup_GLushort=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLushort" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLushort" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLushort" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLUSHORT $fptools_cv_htype_GLushort
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLint" >&5
+echo $ECHO_N "checking Haskell type for GLint... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLint+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLint=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLint=NotReallyATypeCross; fptools_cv_htype_sup_GLint=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLint testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLint=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLint=NotReallyAType; fptools_cv_htype_sup_GLint=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLint" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLint" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLint" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLINT $fptools_cv_htype_GLint
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLuint" >&5
+echo $ECHO_N "checking Haskell type for GLuint... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLuint+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLuint=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLuint=NotReallyATypeCross; fptools_cv_htype_sup_GLuint=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLuint testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLuint=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLuint=NotReallyAType; fptools_cv_htype_sup_GLuint=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLuint" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLuint" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLuint" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLUINT $fptools_cv_htype_GLuint
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLsizei" >&5
+echo $ECHO_N "checking Haskell type for GLsizei... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLsizei+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLsizei=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLsizei=NotReallyATypeCross; fptools_cv_htype_sup_GLsizei=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLsizei testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLsizei=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLsizei=NotReallyAType; fptools_cv_htype_sup_GLsizei=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLsizei" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLsizei" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLsizei" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLSIZEI $fptools_cv_htype_GLsizei
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLenum" >&5
+echo $ECHO_N "checking Haskell type for GLenum... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLenum+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLenum=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLenum=NotReallyATypeCross; fptools_cv_htype_sup_GLenum=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLenum testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLenum=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLenum=NotReallyAType; fptools_cv_htype_sup_GLenum=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLenum" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLenum" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLenum" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLENUM $fptools_cv_htype_GLenum
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLbitfield" >&5
+echo $ECHO_N "checking Haskell type for GLbitfield... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLbitfield+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLbitfield=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLbitfield=NotReallyATypeCross; fptools_cv_htype_sup_GLbitfield=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLbitfield testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLbitfield=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLbitfield=NotReallyAType; fptools_cv_htype_sup_GLbitfield=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLbitfield" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLbitfield" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLbitfield" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLBITFIELD $fptools_cv_htype_GLbitfield
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLfloat" >&5
+echo $ECHO_N "checking Haskell type for GLfloat... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLfloat+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLfloat=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLfloat=NotReallyATypeCross; fptools_cv_htype_sup_GLfloat=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLfloat testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLfloat=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLfloat=NotReallyAType; fptools_cv_htype_sup_GLfloat=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLfloat" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLfloat" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLfloat" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLFLOAT $fptools_cv_htype_GLfloat
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLclampf" >&5
+echo $ECHO_N "checking Haskell type for GLclampf... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLclampf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLclampf=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLclampf=NotReallyATypeCross; fptools_cv_htype_sup_GLclampf=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLclampf testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLclampf=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLclampf=NotReallyAType; fptools_cv_htype_sup_GLclampf=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLclampf" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLclampf" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLclampf" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLCLAMPF $fptools_cv_htype_GLclampf
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLdouble" >&5
+echo $ECHO_N "checking Haskell type for GLdouble... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLdouble+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLdouble=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLdouble=NotReallyATypeCross; fptools_cv_htype_sup_GLdouble=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLdouble testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLdouble=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLdouble=NotReallyAType; fptools_cv_htype_sup_GLdouble=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLdouble" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLdouble" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLdouble" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLDOUBLE $fptools_cv_htype_GLdouble
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLclampd" >&5
+echo $ECHO_N "checking Haskell type for GLclampd... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLclampd+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLclampd=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLclampd=NotReallyATypeCross; fptools_cv_htype_sup_GLclampd=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLclampd testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLclampd=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLclampd=NotReallyAType; fptools_cv_htype_sup_GLclampd=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLclampd" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLclampd" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLclampd" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLCLAMPD $fptools_cv_htype_GLclampd
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLchar" >&5
+echo $ECHO_N "checking Haskell type for GLchar... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLchar+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLchar=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLchar=NotReallyATypeCross; fptools_cv_htype_sup_GLchar=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLchar testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLchar=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLchar=NotReallyAType; fptools_cv_htype_sup_GLchar=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLchar" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLchar" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLchar" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLCHAR $fptools_cv_htype_GLchar
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLintptr" >&5
+echo $ECHO_N "checking Haskell type for GLintptr... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLintptr+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLintptr=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLintptr=NotReallyATypeCross; fptools_cv_htype_sup_GLintptr=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLintptr testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLintptr=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLintptr=NotReallyAType; fptools_cv_htype_sup_GLintptr=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLintptr" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLintptr" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLintptr" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLINTPTR $fptools_cv_htype_GLintptr
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking Haskell type for GLsizeiptr" >&5
+echo $ECHO_N "checking Haskell type for GLsizeiptr... $ECHO_C" >&6; }
+if test "${fptools_cv_htype_GLsizeiptr+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  fptools_cv_htype_sup_GLsizeiptr=yes
+fp_check_htype_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+if test "$cross_compiling" = yes; then
+  fptools_cv_htype_GLsizeiptr=NotReallyATypeCross; fptools_cv_htype_sup_GLsizeiptr=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+#include <stddef.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+
+#if HAVE_TIME_H
+# include <time.h>
+#endif
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if defined(HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined(HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+
+#if defined(HAVE_AL_AL_H)
+# include <AL/al.h>
+#elif defined(HAVE_OPENAL_AL_H)
+# include <OpenAL/al.h>
+#endif
+
+#if defined(HAVE_AL_ALC_H)
+# include <AL/alc.h>
+#elif defined(HAVE_OPENAL_ALC_H)
+# include <OpenAL/alc.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+typedef GLsizeiptr testing;
+
+main() {
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  if (((testing)((int)((testing)1.4))) == ((testing)1.4)) {
+    fprintf(f, "%s%d\n",
+           ((testing)(-1) < (testing)0) ? "Int" : "Word",
+           sizeof(testing)*8);
+  } else {
+    fprintf(f,"%s\n",
+           (sizeof(testing) >  sizeof(double)) ? "LDouble" :
+           (sizeof(testing) == sizeof(double)) ? "Double"  : "Float");
+  }
+  fclose(f);
+  exit(0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  fptools_cv_htype_GLsizeiptr=`cat conftestval`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+fptools_cv_htype_GLsizeiptr=NotReallyAType; fptools_cv_htype_sup_GLsizeiptr=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+CPPFLAGS="$fp_check_htype_save_cppflags"
+fi
+ if test "$fptools_cv_htype_sup_GLsizeiptr" = yes; then
+  { echo "$as_me:$LINENO: result: $fptools_cv_htype_GLsizeiptr" >&5
+echo "${ECHO_T}$fptools_cv_htype_GLsizeiptr" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define HTYPE_GLSIZEIPTR $fptools_cv_htype_GLsizeiptr
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: not supported" >&5
+echo "${ECHO_T}not supported" >&6; }
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define GLU_CFLAGS `echo '' $GLU_CFLAGS | sed -e 's/-[^ ]*/,"&"/g' -e 's/^ *,//'`
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define GLU_LIBS `echo '' $GLU_LIBS | sed -e 's/-[^ ]*/,"&"/g' -e 's/^ *,//'`
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define GLU_FRAMEWORKS `echo '' $GLU_FRAMEWORKS | sed -e 's/-[^ ]*/,"&"/g' -e 's/^ *,//'`
+_ACEOF
+
+
+fi
+
+if test x"$GL_BUILD_PACKAGE" = xyes; then
+  BUILD_PACKAGE_BOOL=True
+else
+  BUILD_PACKAGE_BOOL=False
+fi
+
+
+case "$host" in
+*-mingw32) CALLCONV=stdcall ;;
+*)	CALLCONV=ccall ;;
+esac
+
+
+ac_config_files="$ac_config_files config.mk OpenGL.buildinfo"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      *) $as_unset $ac_var ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    test "x$cache_file" != "x/dev/null" &&
+      { echo "$as_me:$LINENO: updating cache $cache_file" >&5
+echo "$as_me: updating cache $cache_file" >&6;}
+    cat confcache >$cache_file
+  else
+    { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line after each line using $LINENO; the second 'sed'
+  # does the real work.  The second script uses 'N' to pair each
+  # line-number line with the line containing $LINENO, and appends
+  # trailing '-' during substitution so that $LINENO is not a special
+  # case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # scripts with optimization help from Paolo Bonzini.  Blame Lee
+  # E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+  case `echo 'x\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  *)   ECHO_C='\c';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s='ln -s'
+  # ... but there are two gotchas:
+  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+  # In both cases, we have to default to `cp -p'.
+  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+    as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+        test -d "$1/.";
+      else
+	case $1 in
+        -*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by Haskell OpenGL package $as_me 2.2.1, which was
+generated by GNU Autoconf 2.61.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+Haskell OpenGL package config.status 2.2.1
+configured by $0, generated by GNU Autoconf 2.61,
+  with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2006 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    echo "$ac_cs_version"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    { echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  CONFIG_SHELL=$SHELL
+  export CONFIG_SHELL
+  exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "include/HsOpenGLConfig.h") CONFIG_HEADERS="$CONFIG_HEADERS include/HsOpenGLConfig.h" ;;
+    "include/HsOpenGL.h") CONFIG_HEADERS="$CONFIG_HEADERS include/HsOpenGL.h" ;;
+    "config.mk") CONFIG_FILES="$CONFIG_FILES config.mk" ;;
+    "OpenGL.buildinfo") CONFIG_FILES="$CONFIG_FILES OpenGL.buildinfo" ;;
+
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+#
+# Set up the sed scripts for CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "$CONFIG_FILES"; then
+
+_ACEOF
+
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  cat >conf$$subs.sed <<_ACEOF
+SHELL!$SHELL$ac_delim
+PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
+PACKAGE_NAME!$PACKAGE_NAME$ac_delim
+PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
+PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
+PACKAGE_STRING!$PACKAGE_STRING$ac_delim
+PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
+exec_prefix!$exec_prefix$ac_delim
+prefix!$prefix$ac_delim
+program_transform_name!$program_transform_name$ac_delim
+bindir!$bindir$ac_delim
+sbindir!$sbindir$ac_delim
+libexecdir!$libexecdir$ac_delim
+datarootdir!$datarootdir$ac_delim
+datadir!$datadir$ac_delim
+sysconfdir!$sysconfdir$ac_delim
+sharedstatedir!$sharedstatedir$ac_delim
+localstatedir!$localstatedir$ac_delim
+includedir!$includedir$ac_delim
+oldincludedir!$oldincludedir$ac_delim
+docdir!$docdir$ac_delim
+infodir!$infodir$ac_delim
+htmldir!$htmldir$ac_delim
+dvidir!$dvidir$ac_delim
+pdfdir!$pdfdir$ac_delim
+psdir!$psdir$ac_delim
+libdir!$libdir$ac_delim
+localedir!$localedir$ac_delim
+mandir!$mandir$ac_delim
+DEFS!$DEFS$ac_delim
+ECHO_C!$ECHO_C$ac_delim
+ECHO_N!$ECHO_N$ac_delim
+ECHO_T!$ECHO_T$ac_delim
+LIBS!$LIBS$ac_delim
+build_alias!$build_alias$ac_delim
+host_alias!$host_alias$ac_delim
+target_alias!$target_alias$ac_delim
+GL_BUILD_PACKAGE!$GL_BUILD_PACKAGE$ac_delim
+CC!$CC$ac_delim
+CFLAGS!$CFLAGS$ac_delim
+LDFLAGS!$LDFLAGS$ac_delim
+CPPFLAGS!$CPPFLAGS$ac_delim
+ac_ct_CC!$ac_ct_CC$ac_delim
+EXEEXT!$EXEEXT$ac_delim
+OBJEXT!$OBJEXT$ac_delim
+XMKMF!$XMKMF$ac_delim
+CPP!$CPP$ac_delim
+X_CFLAGS!$X_CFLAGS$ac_delim
+X_PRE_LIBS!$X_PRE_LIBS$ac_delim
+X_LIBS!$X_LIBS$ac_delim
+X_EXTRA_LIBS!$X_EXTRA_LIBS$ac_delim
+build!$build$ac_delim
+build_cpu!$build_cpu$ac_delim
+build_vendor!$build_vendor$ac_delim
+build_os!$build_os$ac_delim
+host!$host$ac_delim
+host_cpu!$host_cpu$ac_delim
+host_vendor!$host_vendor$ac_delim
+host_os!$host_os$ac_delim
+target!$target$ac_delim
+target_cpu!$target_cpu$ac_delim
+target_vendor!$target_vendor$ac_delim
+target_os!$target_os$ac_delim
+GLU_FRAMEWORKS!$GLU_FRAMEWORKS$ac_delim
+GLUT_FRAMEWORKS!$GLUT_FRAMEWORKS$ac_delim
+GL_CFLAGS!$GL_CFLAGS$ac_delim
+GL_LIBS!$GL_LIBS$ac_delim
+GLU_CFLAGS!$GLU_CFLAGS$ac_delim
+GLU_LIBS!$GLU_LIBS$ac_delim
+GREP!$GREP$ac_delim
+EGREP!$EGREP$ac_delim
+BUILD_PACKAGE_BOOL!$BUILD_PACKAGE_BOOL$ac_delim
+CALLCONV!$CALLCONV$ac_delim
+LIBOBJS!$LIBOBJS$ac_delim
+LTLIBOBJS!$LTLIBOBJS$ac_delim
+_ACEOF
+
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 75; then
+    break
+  elif $ac_last_try; then
+    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+   { (exit 1); exit 1; }; }
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+  ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
+_ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+:end
+s/|#_!!_#|//g
+CEOF$ac_eof
+_ACEOF
+
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[	 ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+fi # test -n "$CONFIG_FILES"
+
+
+for ac_tag in  :F $CONFIG_FILES  :H $CONFIG_HEADERS
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
+echo "$as_me: error: Invalid tag $ac_tag." >&2;}
+   { (exit 1); exit 1; }; };;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+   { (exit 1); exit 1; }; };;
+      esac
+      ac_file_inputs="$ac_file_inputs $ac_f"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input="Generated from "`IFS=:
+	  echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    fi
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin";;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  { as_dir="$ac_dir"
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+echo "$as_me: error: cannot create directory $as_dir" >&2;}
+   { (exit 1); exit 1; }; }; }
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+case `sed -n '/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+' $ac_file_inputs` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+    s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s&@configure_input@&$configure_input&;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+$ac_datarootdir_hack
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&5
+echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&2;}
+
+  rm -f "$tmp/stdin"
+  case $ac_file in
+  -) cat "$tmp/out"; rm -f "$tmp/out";;
+  *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
+  esac
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+_ACEOF
+
+# Transform confdefs.h into a sed script `conftest.defines', that
+# substitutes the proper values into config.h.in to produce config.h.
+rm -f conftest.defines conftest.tail
+# First, append a space to every undef/define line, to ease matching.
+echo 's/$/ /' >conftest.defines
+# Then, protect against being on the right side of a sed subst, or in
+# an unquoted here document, in config.status.  If some macros were
+# called several times there might be several #defines for the same
+# symbol, which is useless.  But do not sort them, since the last
+# AC_DEFINE must be honored.
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where
+# NAME is the cpp macro being defined, VALUE is the value it is being given.
+# PARAMS is the parameter list in the macro definition--in most cases, it's
+# just an empty string.
+ac_dA='s,^\\([	 #]*\\)[^	 ]*\\([	 ]*'
+ac_dB='\\)[	 (].*,\\1define\\2'
+ac_dC=' '
+ac_dD=' ,'
+
+uniq confdefs.h |
+  sed -n '
+	t rset
+	:rset
+	s/^[	 ]*#[	 ]*define[	 ][	 ]*//
+	t ok
+	d
+	:ok
+	s/[\\&,]/\\&/g
+	s/^\('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p
+	s/^\('"$ac_word_re"'\)[	 ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p
+  ' >>conftest.defines
+
+# Remove the space that was appended to ease matching.
+# Then replace #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+# (The regexp can be short, since the line contains either #define or #undef.)
+echo 's/ $//
+s,^[	 #]*u.*,/* & */,' >>conftest.defines
+
+# Break up conftest.defines:
+ac_max_sed_lines=50
+
+# First sed command is:	 sed -f defines.sed $ac_file_inputs >"$tmp/out1"
+# Second one is:	 sed -f defines.sed "$tmp/out1" >"$tmp/out2"
+# Third one will be:	 sed -f defines.sed "$tmp/out2" >"$tmp/out1"
+# et cetera.
+ac_in='$ac_file_inputs'
+ac_out='"$tmp/out1"'
+ac_nxt='"$tmp/out2"'
+
+while :
+do
+  # Write a here document:
+    cat >>$CONFIG_STATUS <<_ACEOF
+    # First, check the format of the line:
+    cat >"\$tmp/defines.sed" <<\\CEOF
+/^[	 ]*#[	 ]*undef[	 ][	 ]*$ac_word_re[	 ]*\$/b def
+/^[	 ]*#[	 ]*define[	 ][	 ]*$ac_word_re[(	 ]/b def
+b
+:def
+_ACEOF
+  sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+    sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS
+  ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in
+  sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail
+  grep . conftest.tail >/dev/null || break
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines conftest.tail
+
+echo "ac_result=$ac_in" >>$CONFIG_STATUS
+cat >>$CONFIG_STATUS <<\_ACEOF
+  if test x"$ac_file" != x-; then
+    echo "/* $configure_input  */" >"$tmp/config.h"
+    cat "$ac_result" >>"$tmp/config.h"
+    if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f $ac_file
+      mv "$tmp/config.h" $ac_file
+    fi
+  else
+    echo "/* $configure_input  */"
+    cat "$ac_result"
+  fi
+  rm -f "$tmp/out12"
+ ;;
+
+
+  esac
+
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/configure.ac b/configure.ac
new file mode 100644
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,88 @@
+AC_INIT([Haskell OpenGL package], [2.2.1], [sven.panne@aedion.de], [OpenGL])
+
+# Safety check: Ensure that we are in the correct source directory.
+AC_CONFIG_SRCDIR([include/HsOpenGL.h.in])
+
+# The first file mentioned below will be generated by autoheader and contains
+# defines which are needed during package build time only. The second header
+# contains all kinds of stuff which is needed for using this package.
+AC_CONFIG_HEADERS([include/HsOpenGLConfig.h include/HsOpenGL.h])
+
+# We set this to "yes" later when we have found OpenGL libs and headers.
+GL_BUILD_PACKAGE=no
+AC_SUBST([GL_BUILD_PACKAGE])
+
+# Shall we build this package at all?
+FP_ARG_OPENGL
+
+if test x"$enable_opengl" != xno; then
+
+# Check for OpenGL include paths and libraries
+FP_CHECK_GLU
+
+if test x"$GLU_LIBS" = xno; then
+  AC_MSG_FAILURE([no OpenGL library found, so this package cannot be built])
+fi
+
+# check for OpenGL include files
+gl_found_header=no
+glu_found_header=no
+fp_save_cppflags="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+AC_CHECK_HEADERS([GL/gl.h OpenGL/gl.h], [gl_found_header=yes])
+AC_CHECK_HEADERS([GL/glu.h OpenGL/glu.h], [glu_found_header=yes])
+CPPFLAGS="$fp_save_cppflags"
+
+if test x"$gl_found_header" = xno || test x"$glu_found_header" = xno; then
+  AC_MSG_FAILURE([no OpenGL headers found, so this package cannot be built])
+fi
+
+GL_BUILD_PACKAGE=yes
+
+FPTOOLS_CHECK_HTYPE([GLboolean])
+FPTOOLS_CHECK_HTYPE([GLbyte])
+FPTOOLS_CHECK_HTYPE([GLubyte])
+FPTOOLS_CHECK_HTYPE([GLshort])
+FPTOOLS_CHECK_HTYPE([GLushort])
+FPTOOLS_CHECK_HTYPE([GLint])
+FPTOOLS_CHECK_HTYPE([GLuint])
+FPTOOLS_CHECK_HTYPE([GLsizei])
+FPTOOLS_CHECK_HTYPE([GLenum])
+FPTOOLS_CHECK_HTYPE([GLbitfield])
+FPTOOLS_CHECK_HTYPE([GLfloat])
+FPTOOLS_CHECK_HTYPE([GLclampf])
+FPTOOLS_CHECK_HTYPE([GLdouble])
+FPTOOLS_CHECK_HTYPE([GLclampd])
+FPTOOLS_CHECK_HTYPE([GLchar])
+FPTOOLS_CHECK_HTYPE([GLintptr])
+FPTOOLS_CHECK_HTYPE([GLsizeiptr])
+
+AC_DEFINE_UNQUOTED([GLU_CFLAGS],
+  [`echo '' $GLU_CFLAGS | sed -e 's/-[[^ ]]*/,"&"/g' -e 's/^ *,//'`],
+  [C flags for GLU, as a list of string literals.])
+
+AC_DEFINE_UNQUOTED([GLU_LIBS],
+  [`echo '' $GLU_LIBS | sed -e 's/-[[^ ]]*/,"&"/g' -e 's/^ *,//'`],
+  [Library flags for GLU, as a list of string literals.])
+
+AC_DEFINE_UNQUOTED([GLU_FRAMEWORKS],
+  [`echo '' $GLU_FRAMEWORKS | sed -e 's/-[[^ ]]*/,"&"/g' -e 's/^ *,//'`],
+  [Framework flags for GLU, as a list of string literals.])
+
+fi
+
+if test x"$GL_BUILD_PACKAGE" = xyes; then
+  BUILD_PACKAGE_BOOL=True
+else
+  BUILD_PACKAGE_BOOL=False
+fi
+AC_SUBST([BUILD_PACKAGE_BOOL])
+
+case "$host" in
+*-mingw32) CALLCONV=stdcall ;;
+*)	CALLCONV=ccall ;;
+esac
+AC_SUBST([CALLCONV])
+
+AC_CONFIG_FILES([config.mk OpenGL.buildinfo])
+AC_OUTPUT
diff --git a/include/HsOpenGL.h b/include/HsOpenGL.h
new file mode 100644
--- /dev/null
+++ b/include/HsOpenGL.h
@@ -0,0 +1,45 @@
+/* include/HsOpenGL.h.  Generated from HsOpenGL.h.in by configure.  */
+/* -----------------------------------------------------------------------------
+ *
+ * Module      :  C support for Graphics.Rendering.OGL
+ * Copyright   :  (c) Sven Panne 2002-2005
+ * License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+ * 
+ * Maintainer  :  sven.panne@aedion.de
+ * Stability   :  provisional
+ * Portability :  portable
+ *
+ * -------------------------------------------------------------------------- */
+
+#ifndef HSOPENGL_H
+#define HSOPENGL_H
+
+/* Define to 1 if native OpenGL should be used on Mac OS X */
+/* #undef USE_QUARTZ_OPENGL */
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+
+/* for the prototype of wglGetProcAddress */
+#include <windows.h>
+#include <GL/glu.h>
+
+#elif defined(USE_QUARTZ_OPENGL)
+
+#include <OpenGL/glu.h>
+
+#else
+
+/* Hmmm, this seems to be necessary to get a prototype for glXGetProcAddressARB
+   when Mesa is used. Strange... */
+#ifndef GLX_GLXEXT_PROTOTYPES
+#define GLX_GLXEXT_PROTOTYPES
+#endif
+
+#include <GL/glu.h>
+#include <GL/glx.h>
+
+#endif
+
+extern void* hs_OpenGL_getProcAddress(char* procName);
+
+#endif
diff --git a/include/HsOpenGL.h.in b/include/HsOpenGL.h.in
new file mode 100644
--- /dev/null
+++ b/include/HsOpenGL.h.in
@@ -0,0 +1,44 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Module      :  C support for Graphics.Rendering.OGL
+ * Copyright   :  (c) Sven Panne 2002-2005
+ * License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+ * 
+ * Maintainer  :  sven.panne@aedion.de
+ * Stability   :  provisional
+ * Portability :  portable
+ *
+ * -------------------------------------------------------------------------- */
+
+#ifndef HSOPENGL_H
+#define HSOPENGL_H
+
+/* Define to 1 if native OpenGL should be used on Mac OS X */
+#undef USE_QUARTZ_OPENGL
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+
+/* for the prototype of wglGetProcAddress */
+#include <windows.h>
+#include <GL/glu.h>
+
+#elif defined(USE_QUARTZ_OPENGL)
+
+#include <OpenGL/glu.h>
+
+#else
+
+/* Hmmm, this seems to be necessary to get a prototype for glXGetProcAddressARB
+   when Mesa is used. Strange... */
+#ifndef GLX_GLXEXT_PROTOTYPES
+#define GLX_GLXEXT_PROTOTYPES
+#endif
+
+#include <GL/glu.h>
+#include <GL/glx.h>
+
+#endif
+
+extern void* hs_OpenGL_getProcAddress(char* procName);
+
+#endif
diff --git a/include/HsOpenGLConfig.h.in b/include/HsOpenGLConfig.h.in
new file mode 100644
--- /dev/null
+++ b/include/HsOpenGLConfig.h.in
@@ -0,0 +1,124 @@
+/* include/HsOpenGLConfig.h.in.  Generated from configure.ac by autoheader.  */
+
+/* C flags for GLU, as a list of string literals. */
+#undef GLU_CFLAGS
+
+/* Framework flags for GLU, as a list of string literals. */
+#undef GLU_FRAMEWORKS
+
+/* Library flags for GLU, as a list of string literals. */
+#undef GLU_LIBS
+
+/* Define to 1 if you have the <GL/glu.h> header file. */
+#undef HAVE_GL_GLU_H
+
+/* Define to 1 if you have the <GL/gl.h> header file. */
+#undef HAVE_GL_GL_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <OpenGL/glu.h> header file. */
+#undef HAVE_OPENGL_GLU_H
+
+/* Define to 1 if you have the <OpenGL/gl.h> header file. */
+#undef HAVE_OPENGL_GL_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to Haskell type for GLbitfield */
+#undef HTYPE_GLBITFIELD
+
+/* Define to Haskell type for GLboolean */
+#undef HTYPE_GLBOOLEAN
+
+/* Define to Haskell type for GLbyte */
+#undef HTYPE_GLBYTE
+
+/* Define to Haskell type for GLchar */
+#undef HTYPE_GLCHAR
+
+/* Define to Haskell type for GLclampd */
+#undef HTYPE_GLCLAMPD
+
+/* Define to Haskell type for GLclampf */
+#undef HTYPE_GLCLAMPF
+
+/* Define to Haskell type for GLdouble */
+#undef HTYPE_GLDOUBLE
+
+/* Define to Haskell type for GLenum */
+#undef HTYPE_GLENUM
+
+/* Define to Haskell type for GLfloat */
+#undef HTYPE_GLFLOAT
+
+/* Define to Haskell type for GLint */
+#undef HTYPE_GLINT
+
+/* Define to Haskell type for GLintptr */
+#undef HTYPE_GLINTPTR
+
+/* Define to Haskell type for GLshort */
+#undef HTYPE_GLSHORT
+
+/* Define to Haskell type for GLsizei */
+#undef HTYPE_GLSIZEI
+
+/* Define to Haskell type for GLsizeiptr */
+#undef HTYPE_GLSIZEIPTR
+
+/* Define to Haskell type for GLubyte */
+#undef HTYPE_GLUBYTE
+
+/* Define to Haskell type for GLuint */
+#undef HTYPE_GLUINT
+
+/* Define to Haskell type for GLushort */
+#undef HTYPE_GLUSHORT
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if native OpenGL should be used on Mac OS X */
+#undef USE_QUARTZ_OPENGL
+
+/* Define to 1 if the X Window System is missing or not being used. */
+#undef X_DISPLAY_MISSING
diff --git a/include/HsOpenGLExt.h b/include/HsOpenGLExt.h
new file mode 100644
--- /dev/null
+++ b/include/HsOpenGLExt.h
@@ -0,0 +1,29 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Module      :  GL extension support for Graphics.Rendering.OGL
+ * Copyright   :  (c) Sven Panne 2002-2005
+ * License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+ * 
+ * Maintainer  :  sven.panne@aedion.de
+ * Stability   :  provisional
+ * Portability :  portable
+ *
+ * This header should only define preprocessor macros!
+ *
+ * -------------------------------------------------------------------------- */
+
+#ifndef HSOPENGLEXT_H
+#define HSOPENGLEXT_H
+
+/* NOTE: The macro must immediately start with the foreign declaration,
+   otherwise the magic mangler (hack_foreign) in the Hugs build system
+   doesn't recognize it. */
+#define EXTENSION_ENTRY(_msg,_entry,_ty) \
+foreign import CALLCONV unsafe "dynamic" dyn_/**/_entry :: Graphics.Rendering.OGL.GL.Extensions.Invoker (_ty) ; \
+_entry :: (_ty) ; \
+_entry = dyn_/**/_entry ptr_/**/_entry ; \
+ptr_/**/_entry :: FunPtr a ; \
+ptr_/**/_entry = unsafePerformIO (Graphics.Rendering.OGL.GL.Extensions.getProcAddress (_msg) ("_entry")) ; \
+{-# NOINLINE ptr_/**/_entry #-}
+
+#endif
diff --git a/include/HsOpenGLTypes.h b/include/HsOpenGLTypes.h
new file mode 100644
--- /dev/null
+++ b/include/HsOpenGLTypes.h
@@ -0,0 +1,42 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Module      :  Macros for basic GL types to get better Haddock documentation
+ * Copyright   :  (c) Sven Panne 2002-2005
+ * License     :  BSD-style (see the file libraries/OpenGL/LICENSE)
+ * 
+ * Maintainer  :  sven.panne@aedion.de
+ * Stability   :  provisional
+ * Portability :  portable
+ *
+ * This header should only define preprocessor macros!
+ *
+ * -------------------------------------------------------------------------- */
+
+#ifndef HSOPENGLTYPES_H
+#define HSOPENGLTYPES_H
+
+#include "HsOpenGLConfig.h"
+
+/* Using a type synonym in an instance head is not Haskell98, but it is much
+   better for a useful documentation. */
+#ifdef __HADDOCK__
+#define GLbyte_   GLbyte
+#define GLdouble_ GLdouble
+#define GLfloat_  GLfloat
+#define GLint_    GLint
+#define GLshort_  GLshort
+#define GLubyte_  GLubyte
+#define GLuint_   GLuint
+#define GLushort_ GLushort
+#else
+#define GLbyte_   HTYPE_GLBYTE
+#define GLdouble_ HTYPE_GLDOUBLE
+#define GLfloat_  HTYPE_GLFLOAT
+#define GLint_    HTYPE_GLINT
+#define GLshort_  HTYPE_GLSHORT
+#define GLubyte_  HTYPE_GLUBYTE
+#define GLuint_   HTYPE_GLUINT
+#define GLushort_ HTYPE_GLUSHORT
+#endif
+
+#endif
diff --git a/install-sh b/install-sh
new file mode 100644
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,295 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2003-09-24.23
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# 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 THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=
+transform_arg=
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+
+usage="Usage: $0 [OPTION]... SRCFILE DSTFILE
+   or: $0 -d DIR1 DIR2...
+
+In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default.
+In the second, create the directory path DIR.
+
+Options:
+-b=TRANSFORMBASENAME
+-c         copy source (using $cpprog) instead of moving (using $mvprog).
+-d         create directories instead of installing files.
+-g GROUP   $chgrp installed files to GROUP.
+-m MODE    $chmod installed files to MODE.
+-o USER    $chown installed files to USER.
+-s         strip installed files (using $stripprog).
+-t=TRANSFORM
+--help     display this help and exit.
+--version  display version info and exit.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test -n "$1"; do
+  case $1 in
+    -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+        shift
+        continue;;
+
+    -c) instcmd=$cpprog
+        shift
+        continue;;
+
+    -d) dir_arg=true
+        shift
+        continue;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift
+        shift
+        continue;;
+
+    --help) echo "$usage"; exit 0;;
+
+    -m) chmodcmd="$chmodprog $2"
+        shift
+        shift
+        continue;;
+
+    -o) chowncmd="$chownprog $2"
+        shift
+        shift
+        continue;;
+
+    -s) stripcmd=$stripprog
+        shift
+        continue;;
+
+    -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+        shift
+        continue;;
+
+    --version) echo "$0 $scriptversion"; exit 0;;
+
+    *)  if test -z "$src"; then
+          src=$1
+        else
+          # this colon is to work around a 386BSD /bin/sh bug
+          :
+          dst=$1
+        fi
+        shift
+        continue;;
+  esac
+done
+
+if test -z "$src"; then
+  echo "$0: no input file specified." >&2
+  exit 1
+fi
+
+# Protect names starting with `-'.
+case $src in
+  -*) src=./$src ;;
+esac
+
+if test -n "$dir_arg"; then
+  dst=$src
+  src=
+
+  if test -d "$dst"; then
+    instcmd=:
+    chmodcmd=
+  else
+    instcmd=$mkdirprog
+  fi
+else
+  # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+  # might cause directories to be created, which would be especially bad
+  # if $src (and thus $dsttmp) contains '*'.
+  if test ! -f "$src" && test ! -d "$src"; then
+    echo "$0: $src does not exist." >&2
+    exit 1
+  fi
+
+  if test -z "$dst"; then
+    echo "$0: no destination specified." >&2
+    exit 1
+  fi
+
+  # Protect names starting with `-'.
+  case $dst in
+    -*) dst=./$dst ;;
+  esac
+
+  # If destination is a directory, append the input filename; won't work
+  # if double slashes aren't ignored.
+  if test -d "$dst"; then
+    dst=$dst/`basename "$src"`
+  fi
+fi
+
+# This sed command emulates the dirname command.
+dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+
+# Skip lots of stat calls in the usual case.
+if test ! -d "$dstdir"; then
+  defaultIFS='
+	'
+  IFS="${IFS-$defaultIFS}"
+
+  oIFS=$IFS
+  # Some sh's can't handle IFS=/ for some reason.
+  IFS='%'
+  set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+  IFS=$oIFS
+
+  pathcomp=
+
+  while test $# -ne 0 ; do
+    pathcomp=$pathcomp$1
+    shift
+    test -d "$pathcomp" || $mkdirprog "$pathcomp"
+    pathcomp=$pathcomp/
+  done
+fi
+
+if test -n "$dir_arg"; then
+  $doit $instcmd "$dst" \
+    && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+    && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+    && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+    && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
+
+else
+  # If we're going to rename the final executable, determine the name now.
+  if test -z "$transformarg"; then
+    dstfile=`basename "$dst"`
+  else
+    dstfile=`basename "$dst" $transformbasename \
+             | sed $transformarg`$transformbasename
+  fi
+
+  # don't allow the sed command to completely eliminate the filename.
+  test -z "$dstfile" && dstfile=`basename "$dst"`
+
+  # Make a couple of temp file names in the proper directory.
+  dsttmp=$dstdir/_inst.$$_
+  rmtmp=$dstdir/_rm.$$_
+
+  # Trap to clean up those temp files at exit.
+  trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Move or copy the file name to the temp name
+  $doit $instcmd "$src" "$dsttmp" &&
+
+  # and set any options; do chmod last to preserve setuid bits.
+  #
+  # If any of these fail, we abort the whole thing.  If we want to
+  # ignore errors from any of these, just make sure not to ignore
+  # errors from the above "$doit $instcmd $src $dsttmp" command.
+  #
+  { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+    && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+    && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+    && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
+
+  # Now remove or move aside any old file at destination location.  We
+  # try this two ways since rm can't unlink itself on some systems and
+  # the destination file might be busy for other reasons.  In this case,
+  # the final cleanup might fail but the new file should still install
+  # successfully.
+  {
+    if test -f "$dstdir/$dstfile"; then
+      $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
+      || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
+      || {
+	  echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+	  (exit 1); exit
+      }
+    else
+      :
+    fi
+  } &&
+
+  # Now rename the file to the real destination.
+  $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+fi &&
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+  (exit 0); exit
+}
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
