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 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
--------------------------------------------------------------------------------
-- |
-- Module : Graphics.UI.GLUT.DeviceControl
-- Copyright : (c) Sven Panne 2002-2005
-- License : BSD-style (see the file libraries/GLUT/LICENSE)
--
-- Maintainer : sven.panne@aedion.de
-- Stability : stable
-- Portability : portable
--
-- GLUT offers some routines for controlling the key repeat and polling the
-- joystick.
--
--------------------------------------------------------------------------------
module Graphics.UI.GLUT.DeviceControl (
GlobalKeyRepeat(..), globalKeyRepeat,
PerWindowKeyRepeat(..), perWindowKeyRepeat,
forceJoystickCallback
) where
import Foreign.C.Types
import Graphics.Rendering.OpenGL ( StateVar, makeStateVar )
import Graphics.UI.GLUT.QueryUtils
import Graphics.UI.GLUT.Raw
--------------------------------------------------------------------------------
-- | The state of the global key repeat
data GlobalKeyRepeat
= GlobalKeyRepeatOff
| GlobalKeyRepeatOn
| GlobalKeyRepeatDefault
deriving ( Eq, Ord, Show )
marshalGlobalKeyRepeat :: GlobalKeyRepeat -> CInt
marshalGlobalKeyRepeat x = case x of
GlobalKeyRepeatOff -> glut_KEY_REPEAT_OFF
GlobalKeyRepeatOn -> glut_KEY_REPEAT_ON
GlobalKeyRepeatDefault -> glut_KEY_REPEAT_DEFAULT
unmarshalGlobalKeyRepeat :: CInt -> GlobalKeyRepeat
unmarshalGlobalKeyRepeat x
| x == glut_KEY_REPEAT_OFF = GlobalKeyRepeatOff
| x == glut_KEY_REPEAT_ON = GlobalKeyRepeatOn
| x == glut_KEY_REPEAT_DEFAULT = GlobalKeyRepeatDefault
| otherwise = error ("unmarshalGlobalKeyRepeat: illegal value " ++ show x)
--------------------------------------------------------------------------------
-- | Controls the key repeat mode for the window system on a global basis if
-- possible. If supported by the window system, the key repeat can either be
-- disabled, enabled, or set to the window system\'s default key repeat state.
--
-- /X Implementation Notes:/ X11 sends @KeyPress@ events repeatedly when the
-- window system\'s global auto repeat is enabled. 'perWindowKeyRepeat' can
-- prevent these auto repeated keystrokes from being reported as keyboard or
-- special callbacks, but there is still some minimal overhead by the X server
-- to continually stream @KeyPress@ events to the GLUT application. The
-- 'globalKeyRepeat' state variable can be used to actually disable the global
-- sending of auto repeated @KeyPress@ events. Note that 'globalKeyRepeat'
-- affects the global window system auto repeat state so other applications
-- will not auto repeat if you disable auto repeat globally through
-- 'globalKeyRepeat'. GLUT applications using the X11 GLUT implementation
-- should disable key repeat with 'globalKeyRepeat' to disable key repeats most
-- efficiently, but are responsible for explicitly restoring the default key
-- repeat state on exit.
--
-- /Win32 Implementation Notes:/ The Win32 implementation of 'globalKeyRepeat'
-- does nothing. The 'perWindowKeyRepeat' can be used in the Win32 GLUT
-- implementation to ignore repeated keys on a per-window basis without changing
-- the global window system key repeat.
globalKeyRepeat :: StateVar GlobalKeyRepeat
globalKeyRepeat =
makeStateVar (deviceGet unmarshalGlobalKeyRepeat glut_DEVICE_KEY_REPEAT)
(glutSetKeyRepeat . marshalGlobalKeyRepeat)
--------------------------------------------------------------------------------
-- | The state of the per-window key repeat
data PerWindowKeyRepeat
= PerWindowKeyRepeatOff
| PerWindowKeyRepeatOn
deriving ( Eq, Ord, Show )
marshalPerWindowKeyRepeat :: PerWindowKeyRepeat -> CInt
marshalPerWindowKeyRepeat x = case x of
PerWindowKeyRepeatOn -> 0
PerWindowKeyRepeatOff -> 1
unmarshalPerWindowKeyRepeat :: CInt -> PerWindowKeyRepeat
unmarshalPerWindowKeyRepeat x
| x == 0 = PerWindowKeyRepeatOn
| otherwise = PerWindowKeyRepeatOff
--------------------------------------------------------------------------------
-- | Controls if auto repeat keystrokes are reported to the /current window./
-- Ignoring auto repeated keystrokes is generally done in conjunction with using
-- the 'Graphics.UI.GLUT.Callbacks.Window.keyboardMouseCallback'. If you do
-- not ignore auto repeated keystrokes, your GLUT application will experience
-- repeated release\/press callbacks. Games using the keyboard will typically
-- want to ignore key repeat.
perWindowKeyRepeat :: StateVar PerWindowKeyRepeat
perWindowKeyRepeat =
makeStateVar
(deviceGet unmarshalPerWindowKeyRepeat glut_DEVICE_IGNORE_KEY_REPEAT)
(glutIgnoreKeyRepeat . marshalPerWindowKeyRepeat)
--------------------------------------------------------------------------------
-- | Execute the joystick callback set by
-- 'Graphics.UI.GLUT.Callbacks.Window.joystickCallback' once (if one exists).
-- This is done in a synchronous fashion within the current context, i.e. when
-- 'forceJoystickCallback' returns, the callback will have already happened.
forceJoystickCallback :: IO ()
forceJoystickCallback = glutForceJoystickFunc
|