packages feed

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

module Graphics.UI.SDL.Types (
	-- * Type Aliases
	AudioCallback,
	AudioDeviceID,
	AudioFormat,
	Cursor,
	EventFilter,
	FingerID,
	GameController,
	GestureID,
	GLContext,
	Haptic,
	HintCallback,
	Joystick,
	JoystickID,
	Keycode,
	LogOutputFunction,
	Renderer,
	SysWMmsg,
	Texture,
	TimerCallback,
	TimerID,
	TouchID,
	Window,

	-- * Data Structures
	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 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 Keycode = Int32
type LogOutputFunction = FunPtr (Ptr () -> CInt -> LogPriority -> CString -> IO ())
type Renderer = Ptr ()
type SysWMmsg = Ptr ()
type Texture = Ptr ()
type TimerCallback = FunPtr (Word32 -> Ptr () -> IO Word32)
type TimerID = CInt
type TouchID = Int64
type Window = Ptr ()

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
           , 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
           }
           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_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
			_ -> error $ "Unknown type " ++ show typ ++ " for SDL_Event"
		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
			x <- (#peek SDL_Event, button.x) ptr
			y <- (#peek SDL_Event, button.y) ptr
			return $! f wid which button state 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 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.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
		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

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