1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
--------------------------------------------------------------------------------
-- |
-- Module : Graphics.UI.GLUT.Begin
-- Copyright : (c) Sven Panne 2002-2005
-- License : BSD-style (see the file libraries/GLUT/LICENSE)
--
-- Maintainer : sven.panne@aedion.de
-- Stability : stable
-- Portability : portable
--
-- After a GLUT program has done initial setup such as creating windows and
-- menus, GLUT programs enter the GLUT event processing loop by calling
-- 'mainLoop' or handle events iteratively with 'mainLoopEvent'.
--
--------------------------------------------------------------------------------
module Graphics.UI.GLUT.Begin (
-- * Handling events
mainLoop, mainLoopEvent, leaveMainLoop,
-- * Controlling the behaviour when windows are closed
ActionOnWindowClose(..), actionOnWindowClose
) where
import Foreign.C.Types ( CInt )
import Graphics.Rendering.OpenGL.GL.StateVar ( StateVar, makeStateVar )
import Graphics.UI.GLUT.Constants (
glut_ACTION_ON_WINDOW_CLOSE, glut_ACTION_EXIT,
glut_ACTION_GLUTMAINLOOP_RETURNS, glut_ACTION_CONTINUE_EXECUTION )
import Graphics.UI.GLUT.QueryUtils ( simpleGet, glutSetOption )
import Graphics.UI.GLUT.Extensions
--------------------------------------------------------------------------------
#include "HsGLUTExt.h"
--------------------------------------------------------------------------------
-- | Enter the GLUT event processing loop; it will call as necessary any
-- callbacks that have been registered. This routine should be called at most
-- once in a GLUT program.
foreign import CALLCONV safe "glutMainLoop" mainLoop :: IO ()
--------------------------------------------------------------------------------
-- | (/freeglut only/) Process one iteration's worth of events in its event loop.
-- This allows the application to control its own event loop and still use the
-- GLUT package.
mainLoopEvent :: IO ()
mainLoopEvent = glutMainLoopEvent
EXTENSION_ENTRY(safe,"freeglut",glutMainLoopEvent,IO ())
--------------------------------------------------------------------------------
-- | (/freeglut only/) Stop the event loop. If 'actionOnWindowClose' contains
-- 'Exit', the application will exit; otherwise control will return to the
-- function which called 'mainLoop'.
--
-- If the application has two nested calls to 'mainLoop' and calls
-- 'leaveMainLoop', the behaviour is undefined. It may leave only the inner
-- nested loop or it may leave both loops. If the reader has a strong preference
-- for one behaviour over the other he should contact the freeglut Programming
-- Consortium and ask for the code to be fixed.
leaveMainLoop :: IO ()
leaveMainLoop = glutLeaveMainLoop
EXTENSION_ENTRY(safe,"freeglut",glutLeaveMainLoop,IO ())
--------------------------------------------------------------------------------
-- | The behaviour when the user closes a window.
data ActionOnWindowClose
= -- | Exit the whole program when any window is closed or 'leaveMainLoop'
-- is called (default).
Exit
| -- | Return from mainLoop when any window is closed.
MainLoopReturns
| -- | Return from mainLoop after the last window is closed.
ContinueExectuion
deriving ( Eq, Ord, Show )
marshalActionOnWindowClose :: ActionOnWindowClose -> CInt
marshalActionOnWindowClose x = case x of
Exit -> glut_ACTION_EXIT
MainLoopReturns -> glut_ACTION_GLUTMAINLOOP_RETURNS
ContinueExectuion -> glut_ACTION_CONTINUE_EXECUTION
unmarshalActionOnWindowClose :: CInt -> ActionOnWindowClose
unmarshalActionOnWindowClose x
| x == glut_ACTION_EXIT = Exit
| x == glut_ACTION_GLUTMAINLOOP_RETURNS = MainLoopReturns
| x == glut_ACTION_CONTINUE_EXECUTION = ContinueExectuion
| otherwise = error ("unmarshalActionOnWindowClose: illegal value " ++ show x)
-----------------------------------------------------------------------------
-- | (/freeglut only/) Controls the behaviour when the user closes a window.
actionOnWindowClose :: StateVar ActionOnWindowClose
actionOnWindowClose =
makeStateVar
(simpleGet unmarshalActionOnWindowClose glut_ACTION_ON_WINDOW_CLOSE)
(glutSetOption glut_ACTION_ON_WINDOW_CLOSE . marshalActionOnWindowClose)
|