packages feed

sdl2-1.2.0: Graphics/UI/SDL/Types.hsc

module Graphics.UI.SDL.Types (
	-- * Type Aliases
	AudioCallback,
	AudioDeviceID,
	AudioFormat,
	Cond,
	Cursor,
	EventFilter,
	FingerID,
	GameController,
	GestureID,
	GLContext,
	Haptic,
	HintCallback,
	Joystick,
	JoystickID,
	LogOutputFunction,
	Mutex,
	Renderer,
	Sem,
	SpinLock,
	SysWMinfo,
	SysWMmsg,
	Texture,
	Thread,
	ThreadFunction,
	ThreadID,
	TimerCallback,
	TimerID,
	TLSID,
	TouchID,
	Window,

	-- * Data Structures
	Atomic(..),
	AudioCVT(..),
	AudioSpec(..),
	Color(..),
	DisplayMode(..),
	Event(..),
	Finger(..),
	GameControllerButtonBind(..),
	HapticDirection(..),
	HapticEffect(..),
	JoystickGUID(..),
	Keysym(..),
	MessageBoxButtonData(..),
	MessageBoxColor(..),
	MessageBoxColorScheme(..),
	MessageBoxData(..),
	Palette(..),
	PixelFormat(..),
	Point(..),
	Rect(..),
	RendererInfo(..),
	RWops(..),
	Surface(..),
	Version(..)
) where

#include "SDL.h"

import Data.Int
import Data.Word
import Foreign.C.String
import Foreign.C.Types
import Foreign.Marshal.Array
import Foreign.Ptr
import Foreign.Storable
import Graphics.UI.SDL.Enum

type AudioCallback = FunPtr (Ptr () -> Ptr Word8 -> CInt -> IO ())
type AudioDeviceID = Word32
type AudioFormat = Word16
type Cond = Ptr ()
type Cursor = Ptr ()
type EventFilter = FunPtr (Ptr () -> Ptr Event -> IO CInt)
type FingerID = Int64
type GameController = Ptr ()
type GestureID = Int64
type GLContext = Ptr ()
type Haptic = Ptr ()
type HintCallback = FunPtr (Ptr () -> CString -> CString -> CString -> IO ())
type Joystick = Ptr ()
type JoystickID = Int32
type LogOutputFunction = FunPtr (Ptr () -> CInt -> LogPriority -> CString -> IO ())
type Mutex = Ptr ()
type Renderer = Ptr ()
type Sem = Ptr ()
type SpinLock = CInt
type SysWMinfo = Ptr ()
type SysWMmsg = Ptr ()
type Texture = Ptr ()
type Thread = Ptr ()
type ThreadFunction = FunPtr (Ptr () -> IO CInt)
type ThreadID = CULong
type TimerCallback = FunPtr (Word32 -> Ptr () -> IO Word32)
type TimerID = CInt
type TLSID = CUInt
type TouchID = Int64
type Window = Ptr ()

data Atomic = Atomic {
              atomicValue :: CInt
            } deriving (Eq, Show)

instance Storable Atomic where
	sizeOf _ = (#size SDL_atomic_t)
	alignment = sizeOf
	peek ptr = do
		value <- (#peek SDL_atomic_t, value) ptr
		return $! Atomic value
	poke ptr (Atomic value) = do
		(#poke SDL_atomic_t, value) ptr value

data AudioCVT = AudioCVT {
                audioCVTNeeded :: CInt
              , audioCVTSrcFormat :: AudioFormat
              , audioCVTDstFormat :: AudioFormat
              , audioCVTRateIncr :: CDouble
              , audioCVTBuf :: Ptr Word8
              , audioCVTLen :: CInt
              , audioCVTLenCvt :: CInt
              , audioCVTLenMult :: CInt
              , audioCVTLenRatio :: CDouble
              } deriving (Eq, Show)

instance Storable AudioCVT where
	sizeOf _ = (#size SDL_AudioCVT)
	alignment = sizeOf
	peek ptr = do
		needed <- (#peek SDL_AudioCVT, needed) ptr
		src_format <- (#peek SDL_AudioCVT, src_format) ptr
		dst_format <- (#peek SDL_AudioCVT, dst_format) ptr
		rate_incr <- (#peek SDL_AudioCVT, rate_incr) ptr
		buf <- (#peek SDL_AudioCVT, buf) ptr
		len <- (#peek SDL_AudioCVT, len) ptr
		len_cvt <- (#peek SDL_AudioCVT, len_cvt) ptr
		len_mult <- (#peek SDL_AudioCVT, len_mult) ptr
		len_ratio <- (#peek SDL_AudioCVT, len_ratio) ptr
		return $! AudioCVT needed src_format dst_format rate_incr buf len len_cvt len_mult len_ratio
	poke ptr (AudioCVT needed src_format dst_format rate_incr buf len len_cvt len_mult len_ratio) = do
		(#poke SDL_AudioCVT, needed) ptr needed
		(#poke SDL_AudioCVT, src_format) ptr src_format
		(#poke SDL_AudioCVT, dst_format) ptr dst_format
		(#poke SDL_AudioCVT, rate_incr) ptr rate_incr
		(#poke SDL_AudioCVT, buf) ptr buf
		(#poke SDL_AudioCVT, len) ptr len
		(#poke SDL_AudioCVT, len_cvt) ptr len_cvt
		(#poke SDL_AudioCVT, len_mult) ptr len_mult
		(#poke SDL_AudioCVT, len_ratio) ptr len_ratio

data AudioSpec = AudioSpec {
                 audioSpecFreq :: CInt
               , audioSpecFormat :: AudioFormat
               , audioSpecChannels :: Word8
               , audioSpecSilence :: Word8
               , audioSpecSamples :: Word16
               , audioSpecSize :: Word32
               , audioSpecCallback :: AudioCallback
               , audioSpecUserdata :: Ptr ()
               } deriving (Eq, Show)

instance Storable AudioSpec where
	sizeOf _ = (#size SDL_AudioSpec)
	alignment = sizeOf
	peek ptr = do
		freq <- (#peek SDL_AudioSpec, freq) ptr
		format <- (#peek SDL_AudioSpec, format) ptr
		channels <- (#peek SDL_AudioSpec, channels) ptr
		silence <- (#peek SDL_AudioSpec, silence) ptr
		samples <- (#peek SDL_AudioSpec, samples) ptr
		size <- (#peek SDL_AudioSpec, size) ptr
		callback <- (#peek SDL_AudioSpec, callback) ptr
		userdata <- (#peek SDL_AudioSpec, userdata) ptr
		return $! AudioSpec freq format channels silence samples size callback userdata
	poke ptr (AudioSpec freq format channels silence samples size callback userdata) = do
		(#poke SDL_AudioSpec, freq) ptr freq
		(#poke SDL_AudioSpec, format) ptr format
		(#poke SDL_AudioSpec, channels) ptr channels
		(#poke SDL_AudioSpec, silence) ptr silence
		(#poke SDL_AudioSpec, samples) ptr samples
		(#poke SDL_AudioSpec, size) ptr size
		(#poke SDL_AudioSpec, callback) ptr callback
		(#poke SDL_AudioSpec, userdata) ptr userdata

data Color = Color {
             colorR :: Word8
           , colorG :: Word8
           , colorB :: Word8
           , colorA :: Word8
           } deriving (Eq, Show)

instance Storable Color where
	sizeOf _ = (#size SDL_Color)
	alignment = sizeOf
	peek ptr = do
		r <- (#peek SDL_Color, r) ptr
		g <- (#peek SDL_Color, g) ptr
		b <- (#peek SDL_Color, b) ptr
		a <- (#peek SDL_Color, a) ptr
		return $! Color r g b a
	poke ptr (Color r g b a) = do
		(#poke SDL_Color, r) ptr r
		(#poke SDL_Color, g) ptr g
		(#poke SDL_Color, b) ptr b
		(#poke SDL_Color, a) ptr a

data DisplayMode = DisplayMode {
                   displayModeFormat :: Word32
                 , displayModeW :: CInt
                 , displayModeH :: CInt
                 , displayModeRefreshRate :: CInt
                 , displayModeDriverData :: Ptr ()
                 } deriving (Eq, Show)

instance Storable DisplayMode where
	sizeOf _ = (#size SDL_DisplayMode)
	alignment = sizeOf
	peek ptr = do
		format <- (#peek SDL_DisplayMode, format) ptr
		w <- (#peek SDL_DisplayMode, w) ptr
		h <- (#peek SDL_DisplayMode, h) ptr
		refresh_rate <- (#peek SDL_DisplayMode, refresh_rate) ptr
		driverdata <- (#peek SDL_DisplayMode, driverdata) ptr
		return $! DisplayMode format w h refresh_rate driverdata
	poke ptr (DisplayMode format w h refresh_rate driverdata) = do
		(#poke SDL_DisplayMode, format) ptr format
		(#poke SDL_DisplayMode, w) ptr w
		(#poke SDL_DisplayMode, h) ptr h
		(#poke SDL_DisplayMode, refresh_rate) ptr refresh_rate
		(#poke SDL_DisplayMode, driverdata) ptr driverdata

data Event = WindowEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , windowEventWindowID :: Word32
           , windowEventEvent :: Word8
           , windowEventData1 :: Int32
           , windowEventData2 :: Int32
           }
           | KeyboardEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , keyboardEventWindowID :: Word32
           , keyboardEventState :: Word8
           , keyboardEventRepeat :: Word8
           , keyboardEventKeysym :: Keysym
           }
           | TextEditingEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , textEditingEventWindowID :: Word32
           , textEditingEventText :: [CChar]
           , textEditingEventStart :: Int32
           , textEditingEventLength :: Int32
           }
           | TextInputEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , textInputEventWindowID :: Word32
           , textInputEventText :: [CChar]
           }
           | MouseMotionEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , mouseMotionEventWindowID :: Word32
           , mouseMotionEventWhich :: Word32
           , mouseMotionEventState :: Word32
           , mouseMotionEventX :: Int32
           , mouseMotionEventY :: Int32
           , mouseMotionEventXRel :: Int32
           , mouseMotionEventYRel :: Int32
           }
           | MouseButtonEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , mouseButtonEventWindowID :: Word32
           , mouseButtonEventWhich :: Word32
           , mouseButtonEventButton :: Word8
           , mouseButtonEventState :: Word8
           , mouseButtonEventClicks :: Word8
           , mouseButtonEventX :: Int32
           , mouseButtonEventY :: Int32
           }
           | MouseWheelEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , mouseWheelEventWindowID :: Word32
           , mouseWheelEventWhich :: Word32
           , mouseWheelEventX :: Int32
           , mouseWheelEventY :: Int32
           }
           | JoyAxisEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , joyAxisEventWhich :: JoystickID
           , joyAxisEventAxis :: Word8
           , joyAxisEventValue :: Int16
           }
           | JoyBallEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , joyBallEventWhich :: JoystickID
           , joyBallEventBall :: Word8
           , joyBallEventXRel :: Int16
           , joyBallEventYRel :: Int16
           }
           | JoyHatEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , joyHatEventWhich :: JoystickID
           , joyHatEventHat :: Word8
           , joyHatEventValue :: Word8
           }
           | JoyButtonEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , joyButtonEventWhich :: JoystickID
           , joyButtonEventButton :: Word8
           , joyButtonEventState :: Word8
           }
           | JoyDeviceEvent{
             eventType :: Word32
           , eventTimestamp :: Word32
           , joyDeviceEventWhich :: Int32
           }
           | ControllerAxisEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , controllerAxisEventWhich :: JoystickID
           , controllerAxisEventAxis :: Word8
           , controllerAxisEventValue :: Int16
           }
           | ControllerButtonEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , controllerButtonEventWhich :: JoystickID
           , controllerButtonEventButton :: Word8
           , controllerButtonEventState :: Word8
           }
           | ControllerDeviceEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , controllerDeviceEventWhich :: Int32
           }
           | QuitEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           }
           | UserEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , userEventWindowID :: Word32
           , userEventCode :: Int32
           , userEventData1 :: Ptr ()
           , userEventData2 :: Ptr ()
           }
           | SysWMEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , sysWMEventMsg :: SysWMmsg
           }
           | TouchFingerEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , touchFingerEventTouchID :: TouchID
           , touchFingerEventFingerID :: FingerID
           , touchFingerEventX :: CFloat
           , touchFingerEventY :: CFloat
           , touchFingerEventDX :: CFloat
           , touchFingerEventDY :: CFloat
           , touchFingerEventPressure :: CFloat
           }
           | MultiGestureEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , multiGestureEventTouchID :: TouchID
           , multiGestureEventDTheta :: CFloat
           , multiGestureEventDDist :: CFloat
           , multiGestureEventX :: CFloat
           , multiGestureEventY :: CFloat
           , multiGestureEventNumFingers :: Word16
           }
           | DollarGestureEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , dollarGestureEventTouchID :: TouchID
           , dollarGestureEventGestureID :: GestureID
           , dollarGestureEventNumFingers :: Word32
           , dollarGestureEventError :: CFloat
           , dollarGestureEventX :: CFloat
           , dollarGestureEventY :: CFloat
           }
           | DropEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           , dropEventFile :: CString
           }
           | ClipboardUpdateEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           }
           | UnknownEvent {
             eventType :: Word32
           , eventTimestamp :: Word32
           }
           deriving (Eq, Show)

instance Storable Event where
	sizeOf _ = (#size SDL_Event)
	alignment = sizeOf
	peek ptr = do
		typ <- (#peek SDL_Event, common.type) ptr
		timestamp <- (#peek SDL_Event, common.timestamp) ptr
		case typ of
			(#const SDL_QUIT) ->
				return $! QuitEvent typ timestamp
			(#const SDL_WINDOWEVENT) -> do
				wid <- (#peek SDL_Event, window.windowID) ptr
				event <- (#peek SDL_Event, window.event) ptr
				data1 <- (#peek SDL_Event, window.data1) ptr
				data2 <- (#peek SDL_Event, window.data2) ptr
				return $! WindowEvent typ timestamp wid event data1 data2
			(#const SDL_SYSWMEVENT) -> do
				msg <- (#peek SDL_Event, syswm.msg) ptr
				return $! SysWMEvent typ timestamp msg
			(#const SDL_KEYDOWN) -> key $ KeyboardEvent typ timestamp
			(#const SDL_KEYUP) -> key $ KeyboardEvent typ timestamp
			(#const SDL_TEXTEDITING) -> do
				wid <- (#peek SDL_Event, edit.windowID) ptr
				text <- peekArray (#const SDL_TEXTEDITINGEVENT_TEXT_SIZE) $ (#ptr SDL_Event, edit.text) ptr
				start <- (#peek SDL_Event, edit.start) ptr
				len <- (#peek SDL_Event, edit.length) ptr
				return $! TextEditingEvent typ timestamp wid text start len
			(#const SDL_TEXTINPUT) -> do
				wid <- (#peek SDL_Event, text.windowID) ptr
				text <- peekArray (#const SDL_TEXTINPUTEVENT_TEXT_SIZE) $ (#ptr SDL_Event, text.text) ptr
				return $! TextInputEvent typ timestamp wid text
			(#const SDL_MOUSEMOTION) -> do
				wid <- (#peek SDL_Event, motion.windowID) ptr
				which <- (#peek SDL_Event, motion.which) ptr
				state <- (#peek SDL_Event, motion.state) ptr
				x <- (#peek SDL_Event, motion.x) ptr
				y <- (#peek SDL_Event, motion.y) ptr
				xrel <- (#peek SDL_Event, motion.xrel) ptr
				yrel <- (#peek SDL_Event, motion.yrel) ptr
				return $! MouseMotionEvent typ timestamp wid which state x y xrel yrel
			(#const SDL_MOUSEBUTTONDOWN) -> mouse $ MouseButtonEvent typ timestamp
			(#const SDL_MOUSEBUTTONUP) -> mouse $ MouseButtonEvent typ timestamp
			(#const SDL_MOUSEWHEEL) -> do
				wid <- (#peek SDL_Event, wheel.windowID) ptr
				which <- (#peek SDL_Event, wheel.which) ptr
				x <- (#peek SDL_Event, wheel.x) ptr
				y <- (#peek SDL_Event, wheel.y) ptr
				return $! MouseWheelEvent typ timestamp wid which x y
			(#const SDL_JOYAXISMOTION) -> do
				which <- (#peek SDL_Event, jaxis.which) ptr
				axis <- (#peek SDL_Event, jaxis.axis) ptr
				value <- (#peek SDL_Event, jaxis.value) ptr
				return $! JoyAxisEvent typ timestamp which axis value
			(#const SDL_JOYBALLMOTION) -> do
				which <- (#peek SDL_Event, jball.which) ptr
				ball <- (#peek SDL_Event, jball.ball) ptr
				xrel <- (#peek SDL_Event, jball.xrel) ptr
				yrel <- (#peek SDL_Event, jball.yrel) ptr
				return $! JoyBallEvent typ timestamp which ball xrel yrel
			(#const SDL_JOYHATMOTION) -> do
				which <- (#peek SDL_Event, jhat.which) ptr
				hat <- (#peek SDL_Event, jhat.hat) ptr
				value <- (#peek SDL_Event, jhat.value) ptr
				return $! JoyHatEvent typ timestamp which hat value
			(#const SDL_JOYBUTTONDOWN) -> joybutton $ JoyButtonEvent typ timestamp
			(#const SDL_JOYBUTTONUP) -> joybutton $ JoyButtonEvent typ timestamp
			(#const SDL_JOYDEVICEADDED) -> joydevice $ JoyDeviceEvent typ timestamp
			(#const SDL_JOYDEVICEREMOVED) -> joydevice $ JoyDeviceEvent typ timestamp
			(#const SDL_CONTROLLERAXISMOTION) -> do
				which <- (#peek SDL_Event, caxis.which) ptr
				axis <- (#peek SDL_Event, caxis.axis) ptr
				value <- (#peek SDL_Event, caxis.value) ptr
				return $! ControllerButtonEvent typ timestamp which axis value
			(#const SDL_CONTROLLERBUTTONDOWN) -> controllerbutton $ ControllerButtonEvent typ timestamp
			(#const SDL_CONTROLLERBUTTONUP) -> controllerbutton $ ControllerButtonEvent typ timestamp
			(#const SDL_CONTROLLERDEVICEADDED) -> controllerdevice $ ControllerDeviceEvent typ timestamp
			(#const SDL_CONTROLLERDEVICEREMOVED) -> controllerdevice $ ControllerDeviceEvent typ timestamp
			(#const SDL_CONTROLLERDEVICEREMAPPED) -> controllerdevice $ ControllerDeviceEvent typ timestamp
			(#const SDL_FINGERDOWN) -> finger $ TouchFingerEvent typ timestamp
			(#const SDL_FINGERUP) -> finger $ TouchFingerEvent typ timestamp
			(#const SDL_FINGERMOTION) -> finger $ TouchFingerEvent typ timestamp
			(#const SDL_DOLLARGESTURE) -> dollargesture $ DollarGestureEvent typ timestamp
			(#const SDL_DOLLARRECORD) -> dollargesture $ DollarGestureEvent typ timestamp
			(#const SDL_MULTIGESTURE) -> do
				touchId <- (#peek SDL_Event, mgesture.touchId) ptr
				dTheta <- (#peek SDL_Event, mgesture.dTheta) ptr
				dDist <- (#peek SDL_Event, mgesture.dDist) ptr
				x <- (#peek SDL_Event, mgesture.x) ptr
				y <- (#peek SDL_Event, mgesture.y) ptr
				numFingers <- (#peek SDL_Event, mgesture.numFingers) ptr
				return $! MultiGestureEvent typ timestamp touchId dTheta dDist x y numFingers
			(#const SDL_CLIPBOARDUPDATE) ->
				return $! ClipboardUpdateEvent typ timestamp
			(#const SDL_DROPFILE) -> do
				file <- (#peek SDL_Event, drop.file) ptr
				return $! DropEvent typ timestamp file
			x | x >= (#const SDL_USEREVENT) -> do
				wid <- (#peek SDL_Event, user.windowID) ptr
				code <- (#peek SDL_Event, user.code) ptr
				data1 <- (#peek SDL_Event, user.data1) ptr
				data2 <- (#peek SDL_Event, user.data2) ptr
				return $! UserEvent typ timestamp wid code data1 data2
			_ -> return $! UnknownEvent typ timestamp
		where
		key f = do
			wid <- (#peek SDL_Event, key.windowID) ptr
			state <- (#peek SDL_Event, key.state) ptr
			repeat' <- (#peek SDL_Event, key.repeat) ptr
			keysym <- (#peek SDL_Event, key.keysym) ptr
			return $! f wid state repeat' keysym

		mouse f = do
			wid <- (#peek SDL_Event, button.windowID) ptr
			which <- (#peek SDL_Event, button.which) ptr
			button <- (#peek SDL_Event, button.button) ptr
			state <- (#peek SDL_Event, button.state) ptr
			clicks <- (#peek SDL_Event, button.clicks) ptr
			x <- (#peek SDL_Event, button.x) ptr
			y <- (#peek SDL_Event, button.y) ptr
			return $! f wid which button state clicks x y

		joybutton f = do
			which <- (#peek SDL_Event, jbutton.which) ptr
			button <- (#peek SDL_Event, jbutton.button) ptr
			state <- (#peek SDL_Event, jbutton.state) ptr
			return $! f which button state

		joydevice f = do
			which <- (#peek SDL_Event, jdevice.which) ptr
			return $! f which

		controllerbutton f = do
			which <- (#peek SDL_Event, cbutton.which) ptr
			button <- (#peek SDL_Event, cbutton.button) ptr
			state <- (#peek SDL_Event, cbutton.state) ptr
			return $! f which button state

		controllerdevice f = do
			which <- (#peek SDL_Event, cdevice.which) ptr
			return $! f which

		finger f = do
			touchId <- (#peek SDL_Event, tfinger.touchId) ptr
			fingerId <- (#peek SDL_Event, tfinger.fingerId) ptr
			x <- (#peek SDL_Event, tfinger.x) ptr
			y <- (#peek SDL_Event, tfinger.y) ptr
			dx <- (#peek SDL_Event, tfinger.dx) ptr
			dy <- (#peek SDL_Event, tfinger.dy) ptr
			pressure <- (#peek SDL_Event, tfinger.pressure) ptr
			return $! f touchId fingerId x y dx dy pressure

		dollargesture f = do
			touchId <- (#peek SDL_Event, dgesture.touchId) ptr
			gestureId <- (#peek SDL_Event, dgesture.gestureId) ptr
			numFingers <- (#peek SDL_Event, dgesture.numFingers) ptr
			err <- (#peek SDL_Event, dgesture.error) ptr
			x <- (#peek SDL_Event, dgesture.x) ptr
			y <- (#peek SDL_Event, dgesture.y) ptr
			return $! f touchId gestureId numFingers err x y
	poke ptr ev = case ev of
		WindowEvent typ timestamp wid event data1 data2 -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, window.windowID) ptr wid
			(#poke SDL_Event, window.event) ptr event
			(#poke SDL_Event, window.data1) ptr data1
			(#poke SDL_Event, window.data2) ptr data2
		KeyboardEvent typ timestamp wid state repeat' keysym -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, key.windowID) ptr wid
			(#poke SDL_Event, key.state) ptr state
			(#poke SDL_Event, key.repeat) ptr repeat'
			(#poke SDL_Event, key.keysym) ptr keysym
		TextEditingEvent typ timestamp wid text start len -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, edit.windowID) ptr wid
			pokeArray ((#ptr SDL_Event, edit.text) ptr) text
			(#poke SDL_Event, edit.start) ptr start
			(#poke SDL_Event, edit.length) ptr len
		TextInputEvent typ timestamp wid text -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, text.windowID) ptr wid
			pokeArray ((#ptr SDL_Event, text.text) ptr) text
		MouseMotionEvent typ timestamp wid which state x y xrel yrel -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, motion.windowID) ptr wid
			(#poke SDL_Event, motion.which) ptr which
			(#poke SDL_Event, motion.state) ptr state
			(#poke SDL_Event, motion.x) ptr x
			(#poke SDL_Event, motion.y) ptr y
			(#poke SDL_Event, motion.xrel) ptr xrel
			(#poke SDL_Event, motion.yrel) ptr yrel
		MouseButtonEvent typ timestamp wid which button state clicks x y -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, button.windowID) ptr wid
			(#poke SDL_Event, button.which) ptr which
			(#poke SDL_Event, button.button) ptr button
			(#poke SDL_Event, button.state) ptr state
			(#poke SDL_Event, button.clicks) ptr clicks
			(#poke SDL_Event, button.x) ptr x
			(#poke SDL_Event, button.y) ptr y
		MouseWheelEvent typ timestamp wid which x y -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, wheel.windowID) ptr wid
			(#poke SDL_Event, wheel.which) ptr which
			(#poke SDL_Event, wheel.x) ptr x
			(#poke SDL_Event, wheel.y) ptr y
		JoyAxisEvent typ timestamp which axis value -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, jaxis.which) ptr which
			(#poke SDL_Event, jaxis.axis) ptr axis
			(#poke SDL_Event, jaxis.value) ptr value
		JoyBallEvent typ timestamp which ball xrel yrel -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, jball.which) ptr which
			(#poke SDL_Event, jball.ball) ptr ball
			(#poke SDL_Event, jball.xrel) ptr xrel
			(#poke SDL_Event, jball.yrel) ptr yrel
		JoyHatEvent typ timestamp which hat value -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, jhat.which) ptr which
			(#poke SDL_Event, jhat.hat) ptr hat
			(#poke SDL_Event, jhat.value) ptr value
		JoyButtonEvent typ timestamp which button state -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, jbutton.which) ptr which
			(#poke SDL_Event, jbutton.button) ptr button
			(#poke SDL_Event, jbutton.state) ptr state
		JoyDeviceEvent typ timestamp which -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, jdevice.which) ptr which
		ControllerAxisEvent typ timestamp which axis value -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, caxis.which) ptr which
			(#poke SDL_Event, caxis.axis) ptr axis
			(#poke SDL_Event, caxis.value) ptr value
		ControllerButtonEvent typ timestamp which button state -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, cbutton.which) ptr which
			(#poke SDL_Event, cbutton.button) ptr button
			(#poke SDL_Event, cbutton.state) ptr state
		ControllerDeviceEvent typ timestamp which -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, cdevice.which) ptr which
		QuitEvent typ timestamp -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
		UserEvent typ timestamp wid code data1 data2 -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, user.windowID) ptr wid
			(#poke SDL_Event, user.code) ptr code
			(#poke SDL_Event, user.data1) ptr data1
			(#poke SDL_Event, user.data2) ptr data2
		SysWMEvent typ timestamp msg -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, syswm.msg) ptr msg
		TouchFingerEvent typ timestamp touchid fingerid x y dx dy pressure -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, tfinger.touchId) ptr touchid
			(#poke SDL_Event, tfinger.fingerId) ptr fingerid
			(#poke SDL_Event, tfinger.x) ptr x
			(#poke SDL_Event, tfinger.y) ptr y
			(#poke SDL_Event, tfinger.dx) ptr dx
			(#poke SDL_Event, tfinger.dy) ptr dy
			(#poke SDL_Event, tfinger.pressure) ptr pressure
		MultiGestureEvent typ timestamp touchid dtheta ddist x y numfingers -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, mgesture.touchId) ptr touchid
			(#poke SDL_Event, mgesture.dTheta) ptr dtheta
			(#poke SDL_Event, mgesture.dDist) ptr ddist
			(#poke SDL_Event, mgesture.x) ptr x
			(#poke SDL_Event, mgesture.y) ptr y
			(#poke SDL_Event, mgesture.numFingers) ptr numfingers
		DollarGestureEvent typ timestamp touchid gestureid numfingers err x y -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, dgesture.touchId) ptr touchid
			(#poke SDL_Event, dgesture.gestureId) ptr gestureid
			(#poke SDL_Event, dgesture.numFingers) ptr numfingers
			(#poke SDL_Event, dgesture.error) ptr err
			(#poke SDL_Event, dgesture.x) ptr x
			(#poke SDL_Event, dgesture.y) ptr y
		ClipboardUpdateEvent typ timestamp -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
		DropEvent typ timestamp file -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp
			(#poke SDL_Event, drop.file) ptr file
		UnknownEvent typ timestamp -> do
			(#poke SDL_Event, common.type) ptr typ
			(#poke SDL_Event, common.timestamp) ptr timestamp

data Finger = Finger {
              fingerID :: FingerID
            , fingerX :: CFloat
            , fingerY :: CFloat
            , fingerPressure :: CFloat
            } deriving (Eq, Show)

instance Storable Finger where
	sizeOf _ = (#size SDL_Finger)
	alignment = sizeOf
	peek ptr = do
		fingerId <- (#peek SDL_Finger, id) ptr
		x <- (#peek SDL_Finger, x) ptr
		y <- (#peek SDL_Finger, y) ptr
		pressure <- (#peek SDL_Finger, pressure) ptr
		return $! Finger fingerId x y pressure
	poke ptr (Finger fingerId x y pressure) = do
		(#poke SDL_Finger, id) ptr fingerId
		(#poke SDL_Finger, x) ptr x
		(#poke SDL_Finger, y) ptr y
		(#poke SDL_Finger, pressure) ptr pressure

data GameControllerButtonBind = GameControllerButtonBindNone
                              | GameControllerButtonBindButton {
                                gameControllerButtonBindButton :: CInt
                              }
                              | GameControllerButtonBindAxis {
                                gameControllerButtonBindAxis :: CInt
                              }
                              | GameControllerButtonBindHat {
                                gameControllerButtonBindHat :: CInt
                              , gameControllerButtonBindHatMask :: CInt
                              } deriving (Eq, Show)

instance Storable GameControllerButtonBind where
	sizeOf _ = (#size SDL_GameControllerButtonBind)
	alignment = sizeOf
	peek ptr = do
		bind_type <- (#peek SDL_GameControllerButtonBind, bindType) ptr
		case bind_type :: (#type SDL_GameControllerBindType) of
			(#const SDL_CONTROLLER_BINDTYPE_NONE) -> do
				return $! GameControllerButtonBindNone
			(#const SDL_CONTROLLER_BINDTYPE_BUTTON) -> do
				button <- (#peek SDL_GameControllerButtonBind, value.button) ptr
				return $! GameControllerButtonBindButton button
			(#const SDL_CONTROLLER_BINDTYPE_AXIS) -> do
				axis <- (#peek SDL_GameControllerButtonBind, value.axis) ptr
				return $! GameControllerButtonBindAxis axis
			(#const SDL_CONTROLLER_BINDTYPE_HAT) -> do
				hat <- (#peek SDL_GameControllerButtonBind, value.hat.hat) ptr
				hat_mask <- (#peek SDL_GameControllerButtonBind, value.hat.hat_mask) ptr
				return $! GameControllerButtonBindHat hat hat_mask
			_ -> error $ "Unknown type " ++ show bind_type ++ " for SDL_GameControllerButtonBind"
	poke ptr bind = case bind of
		GameControllerButtonBindNone -> do
			(#poke SDL_GameControllerButtonBind, bindType) ptr ((#const SDL_CONTROLLER_BINDTYPE_NONE) :: (#type SDL_GameControllerBindType))
		GameControllerButtonBindButton button -> do
			(#poke SDL_GameControllerButtonBind, bindType) ptr ((#const SDL_CONTROLLER_BINDTYPE_BUTTON) :: (#type SDL_GameControllerBindType))
			(#poke SDL_GameControllerButtonBind, value.button) ptr button
		GameControllerButtonBindAxis axis -> do
			(#poke SDL_GameControllerButtonBind, bindType) ptr ((#const SDL_CONTROLLER_BINDTYPE_AXIS) :: (#type SDL_GameControllerBindType))
			(#poke SDL_GameControllerButtonBind, value.axis) ptr axis
		GameControllerButtonBindHat hat hat_mask -> do
			(#poke SDL_GameControllerButtonBind, bindType) ptr ((#const SDL_CONTROLLER_BINDTYPE_HAT) :: (#type SDL_GameControllerBindType))
			(#poke SDL_GameControllerButtonBind, value.hat.hat) ptr hat
			(#poke SDL_GameControllerButtonBind, value.hat.hat_mask) ptr hat_mask

data HapticDirection = HapticDirection {
                       hapticDirectionType :: Word8
                     , hapticDirectionX :: Int32
                     , hapticDirectionY :: Int32
                     , hapticDirectionZ :: Int32
                     } deriving (Eq, Show)

instance Storable HapticDirection where
	sizeOf _ = (#size SDL_HapticDirection)
	alignment = sizeOf
	peek ptr = do
		typ <- (#peek SDL_HapticDirection, type) ptr
		x <- (#peek SDL_HapticDirection, dir[0]) ptr
		y <- (#peek SDL_HapticDirection, dir[1]) ptr
		z <- (#peek SDL_HapticDirection, dir[2]) ptr
		return $! HapticDirection typ x y z
	poke ptr (HapticDirection typ x y z) = do
		(#poke SDL_HapticDirection, type) ptr typ
		(#poke SDL_HapticDirection, dir[0]) ptr x
		(#poke SDL_HapticDirection, dir[1]) ptr y
		(#poke SDL_HapticDirection, dir[2]) ptr z

data HapticEffect = HapticConstant {
                    hapticEffectType :: Word16
                  , hapticConstantDirection :: HapticDirection
                  , hapticConstantLength :: Word32
                  , hapticConstantDelay :: Word16
                  , hapticConstantButton :: Word16
                  , hapticConstantInterval :: Word16
                  , hapticConstantLevel :: Int16
                  , hapticConstantAttackLength :: Word16
                  , hapticConstantAttackLevel :: Word16
                  , hapticConstantFadeLength :: Word16
                  , hapticConstantFadeLevel :: Word16
                  }
                  | HapticPeriodic {
                    hapticEffectType :: Word16
                  , hapticPeriodicDirection :: HapticDirection
                  , hapticPeriodicLength :: Word32
                  , hapticPeriodicDelay :: Word16
                  , hapticPeriodicButton :: Word16
                  , hapticPeriodicInterval :: Word16
                  , hapticPeriodicPeriod :: Word16
                  , hapticPeriodicMagnitude :: Int16
                  , hapticPeriodicOffset :: Int16
                  , hapticPeriodicPhase :: Word16
                  , hapticPeriodicAttackLength :: Word16
                  , hapticPeriodicAttackLevel :: Word16
                  , hapticPeriodicFadeLength :: Word16
                  , hapticPeriodicFadeLevel :: Word16
                  }
                  | HapticCondition {
                    hapticEffectType :: Word16
                  , hapticConditionLength :: Word32
                  , hapticConditionDelay :: Word16
                  , hapticConditionButton :: Word16
                  , hapticConditionInterval :: Word16
                  , hapticConditionRightSat :: [Word16]
                  , hapticConditionLeftSat :: [Word16]
                  , hapticConditionRightCoeff :: [Int16]
                  , hapticConditionLeftCoeff :: [Int16]
                  , hapticConditionDeadband :: [Word16]
                  , hapticConditionCenter :: [Int16]
                  }
                  | HapticRamp {
                    hapticEffectType :: Word16
                  , hapticRampDirection :: HapticDirection
                  , hapticRampLength :: Word32
                  , hapticRampDelay :: Word16
                  , hapticRampButton :: Word16
                  , hapticRampInterval :: Word16
                  , hapticRampStart :: Int16
                  , hapticRampEnd :: Int16
                  , hapticRampAttackLength :: Word16
                  , hapticRampAttackLevel :: Word16
                  , hapticRampFadeLength :: Word16
                  , hapticRampFadeLevel :: Word16
                  }
                  | HapticLeftRight {
                    hapticEffectType :: Word16
                  , hapticLeftRightLength :: Word32
                  , hapticLeftRightLargeMagnitude :: Word16
                  , hapticLeftRightSmallMagnitude :: Word16
                  }
                  | HapticCustom {
                    hapticEffectType :: Word16
                  , hapticCustomDirection :: HapticDirection
                  , hapticCustomLength :: Word32
                  , hapticCustomDelay :: Word16
                  , hapticCustomButton :: Word16
                  , hapticCustomInterval :: Word16
                  , hapticCustomChannels :: Word8
                  , hapticCustomPeriod :: Word16
                  , hapticCustomSamples :: Word16
                  , hapticCustomData :: Ptr Word16
                  , hapticCustomAttackLength :: Word16
                  , hapticCustomAttackLevel :: Word16
                  , hapticCustomFadeLength :: Word16
                  , hapticCustomFadeLevel :: Word16
                  } deriving (Eq, Show)

instance Storable HapticEffect where
	sizeOf _ = (#size SDL_HapticEffect)
	alignment = sizeOf
	peek ptr = do
		typ <- (#peek SDL_HapticEffect, type) ptr
		case typ of
			(#const SDL_HAPTIC_CONSTANT) -> do
				direction <- (#peek SDL_HapticEffect, constant.direction) ptr
				len <- (#peek SDL_HapticEffect, constant.length) ptr
				delay <- (#peek SDL_HapticEffect, constant.delay) ptr
				button <- (#peek SDL_HapticEffect, constant.button) ptr
				interval <- (#peek SDL_HapticEffect, constant.interval) ptr
				level <- (#peek SDL_HapticEffect, constant.level) ptr
				attack_length <- (#peek SDL_HapticEffect, constant.attack_length) ptr
				attack_level <- (#peek SDL_HapticEffect, constant.attack_level) ptr
				fade_length <- (#peek SDL_HapticEffect, constant.fade_length) ptr
				fade_level <- (#peek SDL_HapticEffect, constant.fade_level) ptr
				return $! HapticConstant typ direction len delay button interval level attack_length attack_level fade_length fade_level

			(#const SDL_HAPTIC_SINE) -> hapticperiodic $ HapticPeriodic typ
			(#const SDL_HAPTIC_TRIANGLE) -> hapticperiodic $ HapticPeriodic typ
			(#const SDL_HAPTIC_SAWTOOTHUP) -> hapticperiodic $ HapticPeriodic typ
			(#const SDL_HAPTIC_SAWTOOTHDOWN) -> hapticperiodic $ HapticPeriodic typ

			(#const SDL_HAPTIC_RAMP) -> do
				direction <- (#peek SDL_HapticEffect, ramp.direction) ptr
				len <- (#peek SDL_HapticEffect, ramp.length) ptr
				delay <- (#peek SDL_HapticEffect, ramp.delay) ptr
				button <- (#peek SDL_HapticEffect, ramp.button) ptr
				interval <- (#peek SDL_HapticEffect, ramp.interval) ptr
				start <- (#peek SDL_HapticEffect, ramp.start) ptr
				end <- (#peek SDL_HapticEffect, ramp.end) ptr
				attack_length <- (#peek SDL_HapticEffect, ramp.attack_length) ptr
				attack_level <- (#peek SDL_HapticEffect, ramp.attack_level) ptr
				fade_length <- (#peek SDL_HapticEffect, ramp.fade_length) ptr
				fade_level <- (#peek SDL_HapticEffect, ramp.fade_level) ptr
				return $! HapticRamp typ direction len delay button interval start end attack_length attack_level fade_length fade_level

			(#const SDL_HAPTIC_SPRING) -> hapticcondition $ HapticCondition typ
			(#const SDL_HAPTIC_DAMPER) -> hapticcondition $ HapticCondition typ
			(#const SDL_HAPTIC_INERTIA) -> hapticcondition $ HapticCondition typ
			(#const SDL_HAPTIC_FRICTION) -> hapticcondition $ HapticCondition typ

			(#const SDL_HAPTIC_LEFTRIGHT) -> do
				len <- (#peek SDL_HapticEffect, leftright.length) ptr
				large_magnitude <- (#peek SDL_HapticEffect, leftright.large_magnitude) ptr
				small_magnitude <- (#peek SDL_HapticEffect, leftright.small_magnitude) ptr
				return $! HapticLeftRight typ len large_magnitude small_magnitude

			(#const SDL_HAPTIC_CUSTOM) -> do
				direction <- (#peek SDL_HapticEffect, custom.direction) ptr
				len <- (#peek SDL_HapticEffect, custom.length) ptr
				delay <- (#peek SDL_HapticEffect, custom.delay) ptr
				button <- (#peek SDL_HapticEffect, custom.button) ptr
				interval <- (#peek SDL_HapticEffect, custom.interval) ptr
				channels <- (#peek SDL_HapticEffect, custom.channels) ptr
				period <- (#peek SDL_HapticEffect, custom.period) ptr
				samples <- (#peek SDL_HapticEffect, custom.samples) ptr
				datum <- (#peek SDL_HapticEffect, custom.data) ptr
				attack_length <- (#peek SDL_HapticEffect, custom.attack_length) ptr
				attack_level <- (#peek SDL_HapticEffect, custom.attack_level) ptr
				fade_length <- (#peek SDL_HapticEffect, custom.fade_length) ptr
				fade_level <- (#peek SDL_HapticEffect, custom.fade_level) ptr
				return $! HapticCustom typ direction len delay button interval channels period samples datum attack_length attack_level fade_length fade_level
			_ -> error $ "Unknown type " ++ show typ ++ " for SDL_HapticEffect"
		where
		hapticperiodic f = do
			direction <- (#peek SDL_HapticEffect, periodic.direction) ptr
			len <- (#peek SDL_HapticEffect, periodic.length) ptr
			delay <- (#peek SDL_HapticEffect, periodic.delay) ptr
			button <- (#peek SDL_HapticEffect, periodic.button) ptr
			interval <- (#peek SDL_HapticEffect, periodic.interval) ptr
			period <- (#peek SDL_HapticEffect, periodic.period) ptr
			magnitude <- (#peek SDL_HapticEffect, periodic.magnitude) ptr
			offset <- (#peek SDL_HapticEffect, periodic.offset) ptr
			phase <- (#peek SDL_HapticEffect, periodic.phase) ptr
			attack_length <- (#peek SDL_HapticEffect, periodic.attack_length) ptr
			attack_level <- (#peek SDL_HapticEffect, periodic.attack_level) ptr
			fade_length <- (#peek SDL_HapticEffect, periodic.fade_length) ptr
			fade_level <- (#peek SDL_HapticEffect, periodic.fade_level) ptr
			return $! f direction len delay button interval period magnitude offset phase attack_length attack_level fade_length fade_level

		hapticcondition f = do
			len <- (#peek SDL_HapticEffect, condition.length) ptr
			delay <- (#peek SDL_HapticEffect, condition.delay) ptr
			button <- (#peek SDL_HapticEffect, condition.button) ptr
			interval <- (#peek SDL_HapticEffect, condition.interval) ptr
			right_sat <- peekArray 3 $ (#ptr SDL_HapticEffect, condition.right_sat) ptr
			left_sat <- peekArray 3 $ (#ptr SDL_HapticEffect, condition.left_sat) ptr
			right_coeff <- peekArray 3 $ (#ptr SDL_HapticEffect, condition.right_coeff) ptr
			left_coeff <- peekArray 3 $ (#ptr SDL_HapticEffect, condition.left_coeff) ptr
			deadband <- peekArray 3 $ (#ptr SDL_HapticEffect, condition.deadband) ptr
			center <- peekArray 3 $ (#ptr SDL_HapticEffect, condition.center) ptr
			return $! f len delay button interval right_sat left_sat right_coeff left_coeff deadband center
	poke ptr event = case event of
		HapticConstant typ direction len delay button interval level attack_length attack_level fade_length fade_level -> do
			(#poke SDL_HapticEffect, type) ptr typ
			(#poke SDL_HapticEffect, constant.direction) ptr direction
			(#poke SDL_HapticEffect, constant.length) ptr len
			(#poke SDL_HapticEffect, constant.delay) ptr delay
			(#poke SDL_HapticEffect, constant.button) ptr button
			(#poke SDL_HapticEffect, constant.interval) ptr interval
			(#poke SDL_HapticEffect, constant.level) ptr level
			(#poke SDL_HapticEffect, constant.attack_length) ptr attack_length
			(#poke SDL_HapticEffect, constant.attack_level) ptr attack_level
			(#poke SDL_HapticEffect, constant.fade_length) ptr fade_length
			(#poke SDL_HapticEffect, constant.fade_level) ptr fade_level
		HapticPeriodic typ direction len delay button interval period magnitude offset phase attack_length attack_level fade_length fade_level -> do
			(#poke SDL_HapticEffect, type) ptr typ
			(#poke SDL_HapticEffect, periodic.direction) ptr direction
			(#poke SDL_HapticEffect, periodic.length) ptr len
			(#poke SDL_HapticEffect, periodic.delay) ptr delay
			(#poke SDL_HapticEffect, periodic.button) ptr button
			(#poke SDL_HapticEffect, periodic.interval) ptr interval
			(#poke SDL_HapticEffect, periodic.period) ptr period
			(#poke SDL_HapticEffect, periodic.magnitude) ptr magnitude
			(#poke SDL_HapticEffect, periodic.offset) ptr offset
			(#poke SDL_HapticEffect, periodic.phase) ptr phase
			(#poke SDL_HapticEffect, periodic.attack_length) ptr attack_length
			(#poke SDL_HapticEffect, periodic.attack_level) ptr attack_level
			(#poke SDL_HapticEffect, periodic.fade_length) ptr fade_length
			(#poke SDL_HapticEffect, periodic.fade_level) ptr fade_level
		HapticCondition typ len delay button interval right_sat left_sat right_coeff left_coeff deadband center -> do
			(#poke SDL_HapticEffect, type) ptr typ
			(#poke SDL_HapticEffect, condition.length) ptr len
			(#poke SDL_HapticEffect, condition.delay) ptr delay
			(#poke SDL_HapticEffect, condition.button) ptr button
			(#poke SDL_HapticEffect, condition.interval) ptr interval
			pokeArray ((#ptr SDL_HapticEffect, condition.right_sat) ptr) right_sat
			pokeArray ((#ptr SDL_HapticEffect, condition.left_sat) ptr) left_sat
			pokeArray ((#ptr SDL_HapticEffect, condition.right_coeff) ptr) right_coeff
			pokeArray ((#ptr SDL_HapticEffect, condition.left_coeff) ptr) left_coeff
			pokeArray ((#ptr SDL_HapticEffect, condition.deadband) ptr) deadband
			pokeArray ((#ptr SDL_HapticEffect, condition.center) ptr) center
		HapticRamp typ direction len delay button interval start end attack_length attack_level fade_length fade_level -> do
			(#poke SDL_HapticEffect, type) ptr typ
			(#poke SDL_HapticEffect, ramp.direction) ptr direction
			(#poke SDL_HapticEffect, ramp.length) ptr len
			(#poke SDL_HapticEffect, ramp.delay) ptr delay
			(#poke SDL_HapticEffect, ramp.button) ptr button
			(#poke SDL_HapticEffect, ramp.interval) ptr interval
			(#poke SDL_HapticEffect, ramp.start) ptr start
			(#poke SDL_HapticEffect, ramp.end) ptr end
			(#poke SDL_HapticEffect, ramp.attack_length) ptr attack_length
			(#poke SDL_HapticEffect, ramp.attack_level) ptr attack_level
			(#poke SDL_HapticEffect, ramp.fade_length) ptr fade_length
			(#poke SDL_HapticEffect, ramp.fade_level) ptr fade_level
		HapticLeftRight typ len large_magnitude small_magnitude -> do
			(#poke SDL_HapticEffect, type) ptr typ
			(#poke SDL_HapticEffect, leftright.length) ptr len
			(#poke SDL_HapticEffect, leftright.large_magnitude) ptr large_magnitude
			(#poke SDL_HapticEffect, leftright.small_magnitude) ptr small_magnitude
		HapticCustom typ direction len delay button interval channels period samples datum attack_length attack_level fade_length fade_level -> do
			(#poke SDL_HapticEffect, type) ptr typ
			(#poke SDL_HapticEffect, custom.direction) ptr direction
			(#poke SDL_HapticEffect, custom.length) ptr len
			(#poke SDL_HapticEffect, custom.delay) ptr delay
			(#poke SDL_HapticEffect, custom.button) ptr button
			(#poke SDL_HapticEffect, custom.interval) ptr interval
			(#poke SDL_HapticEffect, custom.channels) ptr channels
			(#poke SDL_HapticEffect, custom.period) ptr period
			(#poke SDL_HapticEffect, custom.samples) ptr samples
			(#poke SDL_HapticEffect, custom.data) ptr datum
			(#poke SDL_HapticEffect, custom.attack_length) ptr attack_length
			(#poke SDL_HapticEffect, custom.attack_level) ptr attack_level
			(#poke SDL_HapticEffect, custom.fade_length) ptr fade_length
			(#poke SDL_HapticEffect, custom.fade_level) ptr fade_level

data JoystickGUID = JoystickGUID {
                    joystickGUID :: [Word8]
                  } deriving (Eq, Show)

instance Storable JoystickGUID where
	sizeOf _ = (#size SDL_JoystickGUID)
	alignment = sizeOf
	peek ptr = do
		guid <- peekArray 16 $ (#ptr SDL_JoystickGUID, data) ptr
		return $! JoystickGUID guid
	poke ptr (JoystickGUID guid) =
		pokeArray ((#ptr SDL_JoystickGUID, data) ptr) guid

data Keysym = Keysym {
              keysymScancode :: Scancode
            , keysymKeycode :: Keycode
            , keysymMod :: Word16
            } deriving (Eq, Show)

instance Storable Keysym where
	sizeOf _ = (#size SDL_Keysym)
	alignment = sizeOf
	peek ptr = do
		scancode <- (#peek SDL_Keysym, scancode) ptr
		sym <- (#peek SDL_Keysym, sym) ptr
		mod' <- (#peek SDL_Keysym, mod) ptr
		return $! Keysym scancode sym mod'
	poke ptr (Keysym scancode sym mod') = do
		(#poke SDL_Keysym, scancode) ptr scancode
		(#poke SDL_Keysym, sym) ptr sym
		(#poke SDL_Keysym, mod) ptr mod'

data MessageBoxButtonData = MessageBoxButtonData {
                            messageBoxButtonDataFlags :: Word32
                          , messageBoxButtonButtonID :: CInt
                          , messageBoxButtonText :: CString
                          } deriving (Eq, Show)

instance Storable MessageBoxButtonData where
	sizeOf _ = (#size SDL_MessageBoxButtonData)
	alignment = sizeOf
	peek ptr = do
		flags <- (#peek SDL_MessageBoxButtonData, flags) ptr
		buttonid <- (#peek SDL_MessageBoxButtonData, buttonid) ptr
		text <- (#peek SDL_MessageBoxButtonData, text) ptr
		return $! MessageBoxButtonData flags buttonid text
	poke ptr (MessageBoxButtonData flags buttonid text) = do
		(#poke SDL_MessageBoxButtonData, flags) ptr flags
		(#poke SDL_MessageBoxButtonData, buttonid) ptr buttonid
		(#poke SDL_MessageBoxButtonData, text) ptr text

data MessageBoxColor = MessageBoxColor {
                       messageBoxColorR :: Word8
                     , messageBoxColorG :: Word8
                     , messageBoxColorB :: Word8
                     } deriving (Eq, Show)

instance Storable MessageBoxColor where
	sizeOf _ = (#size SDL_MessageBoxColor)
	alignment = sizeOf
	peek ptr = do
		r <- (#peek SDL_MessageBoxColor, r) ptr
		g <- (#peek SDL_MessageBoxColor, g) ptr
		b <- (#peek SDL_MessageBoxColor, b) ptr
		return $! MessageBoxColor r g b
	poke ptr (MessageBoxColor r g b) = do
		(#poke SDL_MessageBoxColor, r) ptr r
		(#poke SDL_MessageBoxColor, g) ptr g
		(#poke SDL_MessageBoxColor, b) ptr b

data MessageBoxColorScheme = MessageBoxColorScheme {
                             messageBoxColorSchemeColorBackground :: MessageBoxColor
                           , messageBoxColorSchemeColorText :: MessageBoxColor
                           , messageBoxColorSchemeColorButtonBorder :: MessageBoxColor
                           , messageBoxColorSchemeColorButtonBackground :: MessageBoxColor
                           , messageBoxColorSchemeColorButtonSelected :: MessageBoxColor
                           } deriving (Eq, Show)

instance Storable MessageBoxColorScheme where
	sizeOf _ = (#size SDL_MessageBoxColorScheme)
	alignment = sizeOf
	peek ptr = do
		background <- (#peek SDL_MessageBoxColorScheme, colors[SDL_MESSAGEBOX_COLOR_BACKGROUND]) ptr
		text <- (#peek SDL_MessageBoxColorScheme, colors[SDL_MESSAGEBOX_COLOR_TEXT]) ptr
		button_border <- (#peek SDL_MessageBoxColorScheme, colors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER]) ptr
		button_background <- (#peek SDL_MessageBoxColorScheme, colors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND]) ptr
		button_selected <- (#peek SDL_MessageBoxColorScheme, colors[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED]) ptr
		return $! MessageBoxColorScheme background text button_border button_background button_selected
	poke ptr (MessageBoxColorScheme background text button_border button_background button_selected) = do
		(#poke SDL_MessageBoxColorScheme, colors[SDL_MESSAGEBOX_COLOR_BACKGROUND]) ptr background
		(#poke SDL_MessageBoxColorScheme, colors[SDL_MESSAGEBOX_COLOR_TEXT]) ptr text
		(#poke SDL_MessageBoxColorScheme, colors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER]) ptr button_border
		(#poke SDL_MessageBoxColorScheme, colors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND]) ptr button_background
		(#poke SDL_MessageBoxColorScheme, colors[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED]) ptr button_selected

data MessageBoxData = MessageBoxData {
                      messageBoxDataFlags :: Word32
                    , messageBoxDataWindow :: Window
                    , messageBoxDataTitle :: CString
                    , messageBoxDataMessage :: CString
                    , messageBoxDataNumButtons :: CInt
                    , messageBoxDataButtons :: Ptr MessageBoxButtonData
                    , messageBoxDataColorScheme :: Ptr MessageBoxColorScheme
                    } deriving (Eq, Show)

instance Storable MessageBoxData where
	sizeOf _ = (#size SDL_MessageBoxData)
	alignment = sizeOf
	peek ptr = do
		flags <- (#peek SDL_MessageBoxData, flags) ptr
		window <- (#peek SDL_MessageBoxData, window) ptr
		title <- (#peek SDL_MessageBoxData, title) ptr
		message <- (#peek SDL_MessageBoxData, message) ptr
		numbuttons <- (#peek SDL_MessageBoxData, numbuttons) ptr
		buttons <- (#peek SDL_MessageBoxData, buttons) ptr
		color_scheme <- (#peek SDL_MessageBoxData, colorScheme) ptr
		return $! MessageBoxData flags window title message numbuttons buttons color_scheme
	poke ptr (MessageBoxData flags window title message numbuttons buttons color_scheme) = do
		(#poke SDL_MessageBoxData, flags) ptr flags
		(#poke SDL_MessageBoxData, window) ptr window
		(#poke SDL_MessageBoxData, title) ptr title
		(#poke SDL_MessageBoxData, message) ptr message
		(#poke SDL_MessageBoxData, numbuttons) ptr numbuttons
		(#poke SDL_MessageBoxData, buttons) ptr buttons
		(#poke SDL_MessageBoxData, colorScheme) ptr color_scheme

data Palette = Palette {
               paletteNColors :: CInt
             , paletteColors :: Ptr Color
             } deriving (Eq, Show)

instance Storable Palette where
	sizeOf _ = (#size SDL_Palette)
	alignment = sizeOf
	peek ptr = do
		ncolors <- (#peek SDL_Palette, ncolors) ptr
		colors <- (#peek SDL_Palette, colors) ptr
		return $! Palette ncolors colors
	poke ptr (Palette ncolors colors) = do
		(#poke SDL_Palette, ncolors) ptr ncolors
		(#poke SDL_Palette, colors) ptr colors

data PixelFormat = PixelFormat {
                   pixelFormatFormat :: Word32
                 , pixelFormatPalette :: Ptr Palette
                 , pixelFormatBitsPerPixel :: Word8
                 , pixelFormatBytesPerPixel :: Word8
                 , pixelFormatRMask :: Word32
                 , pixelFormatGMask :: Word32
                 , pixelFormatBMask :: Word32
                 , pixelFormatAMask :: Word32
                 } deriving (Eq, Show)

instance Storable PixelFormat where
	sizeOf _ = (#size SDL_PixelFormat)
	alignment = sizeOf
	peek ptr = do
		format <- (#peek SDL_PixelFormat, format) ptr
		palette <- (#peek SDL_PixelFormat, palette) ptr
		bits_per_pixel <- (#peek SDL_PixelFormat, BitsPerPixel) ptr
		bytes_per_pixel <- (#peek SDL_PixelFormat, BytesPerPixel) ptr
		rmask <- (#peek SDL_PixelFormat, Rmask) ptr
		gmask <- (#peek SDL_PixelFormat, Gmask) ptr
		bmask <- (#peek SDL_PixelFormat, Bmask) ptr
		amask <- (#peek SDL_PixelFormat, Amask) ptr
		return $! PixelFormat format palette bits_per_pixel bytes_per_pixel rmask gmask bmask amask
	poke ptr (PixelFormat format palette bits_per_pixel bytes_per_pixel rmask gmask bmask amask) = do
		(#poke SDL_PixelFormat, format) ptr format
		(#poke SDL_PixelFormat, palette) ptr palette
		(#poke SDL_PixelFormat, BitsPerPixel) ptr bits_per_pixel
		(#poke SDL_PixelFormat, BytesPerPixel) ptr bytes_per_pixel
		(#poke SDL_PixelFormat, Rmask) ptr rmask
		(#poke SDL_PixelFormat, Gmask) ptr gmask
		(#poke SDL_PixelFormat, Bmask) ptr bmask
		(#poke SDL_PixelFormat, Amask) ptr amask

data Point = Point {
             pointX :: CInt
           , pointY :: CInt
           } deriving (Eq, Show)

instance Storable Point where
	sizeOf _ = (#size SDL_Point)
	alignment = sizeOf
	peek ptr = do
		x <- (#peek SDL_Point, x) ptr
		y <- (#peek SDL_Point, y) ptr
		return $! Point x y
	poke ptr (Point x y) = do
		(#poke SDL_Point, x) ptr x
		(#poke SDL_Point, y) ptr y

data Rect = Rect {
            rectX :: CInt
          , rectY :: CInt
          , rectW :: CInt
          , rectH :: CInt
          } deriving (Eq, Show)

instance Storable Rect where
	sizeOf _ = (#size SDL_Rect)
	alignment = sizeOf
	peek ptr = do
		x <- (#peek SDL_Rect, x) ptr
		y <- (#peek SDL_Rect, y) ptr
		w <- (#peek SDL_Rect, w) ptr
		h <- (#peek SDL_Rect, h) ptr
		return $! Rect x y w h
	poke ptr (Rect x y w h) = do
		(#poke SDL_Rect, x) ptr x
		(#poke SDL_Rect, y) ptr y
		(#poke SDL_Rect, w) ptr w
		(#poke SDL_Rect, h) ptr h

data RendererInfo = RendererInfo {
                    rendererInfoName :: CString
                  , rendererInfoFlags :: Word32
                  , rendererInfoNumTextureFormats :: Word32
                  , rendererInfoTextureFormats :: [Word32]
                  , rendererInfoMaxTextureWidth :: CInt
                  , rendererInfoMaxTextureHeight :: CInt
                  } deriving (Eq, Show)

instance Storable RendererInfo where
	sizeOf _ = (#size SDL_RendererInfo)
	alignment = sizeOf
	peek ptr = do
		name <- (#peek SDL_RendererInfo, name) ptr
		flags <- (#peek SDL_RendererInfo, flags) ptr
		num_texture_formats <- (#peek SDL_RendererInfo, num_texture_formats) ptr
		texture_formats <- peekArray 16 $ (#ptr SDL_RendererInfo, texture_formats) ptr
		max_texture_width <- (#peek SDL_RendererInfo, max_texture_width) ptr
		max_texture_height <- (#peek SDL_RendererInfo, max_texture_height) ptr
		return $! RendererInfo name flags num_texture_formats texture_formats max_texture_width max_texture_height
	poke ptr (RendererInfo name flags num_texture_formats texture_formats max_texture_width max_texture_height) = do
		(#poke SDL_RendererInfo, name) ptr name
		(#poke SDL_RendererInfo, flags) ptr flags
		(#poke SDL_RendererInfo, num_texture_formats) ptr num_texture_formats
		pokeArray ((#ptr SDL_RendererInfo, texture_formats) ptr) texture_formats
		(#poke SDL_RendererInfo, max_texture_width) ptr max_texture_width
		(#poke SDL_RendererInfo, max_texture_height) ptr max_texture_height

data RWops = RWops {
             rwopsSize :: FunPtr (Ptr RWops -> IO Int64)
           , rwopsSeek :: FunPtr (Ptr RWops -> Int64 -> CInt -> IO Int64)
           , rwopsRead :: FunPtr (Ptr RWops -> Ptr () -> CSize -> CSize -> IO CSize)
           , rwopsWrite :: FunPtr (Ptr RWops -> Ptr () -> CSize -> CSize -> IO CSize)
           , rwopsClose :: FunPtr (Ptr RWops -> IO CInt)
           , rwopsType :: Word32
           } deriving (Eq, Show)

instance Storable RWops where
	sizeOf _ = (#size SDL_RWops)
	alignment = sizeOf
	peek ptr = do
		size <- (#peek SDL_RWops, size) ptr
		seek <- (#peek SDL_RWops, seek) ptr
		read' <- (#peek SDL_RWops, read) ptr
		write <- (#peek SDL_RWops, write) ptr
		close <- (#peek SDL_RWops, close) ptr
		typ <- (#peek SDL_RWops, type) ptr
		return $! RWops size seek read' write close typ
	poke ptr (RWops size seek read' write close typ) = do
		(#poke SDL_RWops, size) ptr size
		(#poke SDL_RWops, seek) ptr seek
		(#poke SDL_RWops, read) ptr read'
		(#poke SDL_RWops, write) ptr write
		(#poke SDL_RWops, close) ptr close
		(#poke SDL_RWops, type) ptr typ

data Surface = Surface {
               surfaceFormat :: Ptr PixelFormat
             , surfaceW :: CInt
             , surfaceH :: CInt
             , surfacePixels :: Ptr ()
             , surfaceUserdata :: Ptr ()
             , surfaceClipRect :: Rect
             , surfaceRefcount :: CInt
             } deriving (Eq, Show)

instance Storable Surface where
	sizeOf _ = (#size SDL_Surface)
	alignment = sizeOf
	peek ptr = do
		format <- (#peek SDL_Surface, format) ptr
		w <- (#peek SDL_Surface, w) ptr
		h <- (#peek SDL_Surface, h) ptr
		pixels <- (#peek SDL_Surface, pixels) ptr
		userdata <- (#peek SDL_Surface, userdata) ptr
		cliprect <- (#peek SDL_Surface, clip_rect) ptr
		refcount <- (#peek SDL_Surface, refcount) ptr
		return $! Surface format w h pixels userdata cliprect refcount
	poke ptr (Surface format w h pixels userdata cliprect refcount) = do
		(#poke SDL_Surface, format) ptr format
		(#poke SDL_Surface, w) ptr w
		(#poke SDL_Surface, h) ptr h
		(#poke SDL_Surface, pixels) ptr pixels
		(#poke SDL_Surface, userdata) ptr userdata
		(#poke SDL_Surface, clip_rect) ptr cliprect
		(#poke SDL_Surface, refcount) ptr refcount

data Version = Version {
               versionMajor :: Word8
             , versionMinor :: Word8
             , versionPatch :: Word8
             } deriving (Eq, Show)

instance Storable Version where
	sizeOf _ = (#size SDL_version)
	alignment = sizeOf
	peek ptr = do
		major <- (#peek SDL_version, major) ptr
		minor <- (#peek SDL_version, minor) ptr
		patch <- (#peek SDL_version, patch) ptr
		return $! Version major minor patch
	poke ptr (Version major minor patch) = do
		(#poke SDL_version, major) ptr major
		(#poke SDL_version, minor) ptr minor
		(#poke SDL_version, patch) ptr patch