diff --git a/Graphics/UI/SDL.hs b/Graphics/UI/SDL.hs
--- a/Graphics/UI/SDL.hs
+++ b/Graphics/UI/SDL.hs
@@ -1,3 +1,4 @@
+-- | Raw low-level FFI bindings to the sdl2 C library.
 module Graphics.UI.SDL (
 	module Graphics.UI.SDL.Audio,
 	module Graphics.UI.SDL.Basic,
@@ -5,7 +6,9 @@
 	module Graphics.UI.SDL.Event,
 	module Graphics.UI.SDL.Filesystem,
 	module Graphics.UI.SDL.Haptic,
+	module Graphics.UI.SDL.Platform,
 	module Graphics.UI.SDL.Power,
+	module Graphics.UI.SDL.Thread,
 	module Graphics.UI.SDL.Timer,
 	module Graphics.UI.SDL.Types,
 	module Graphics.UI.SDL.Video
@@ -17,7 +20,9 @@
 import Graphics.UI.SDL.Event
 import Graphics.UI.SDL.Filesystem
 import Graphics.UI.SDL.Haptic
+import Graphics.UI.SDL.Platform
 import Graphics.UI.SDL.Power
+import Graphics.UI.SDL.Thread
 import Graphics.UI.SDL.Timer
 import Graphics.UI.SDL.Types
 import Graphics.UI.SDL.Video
diff --git a/Graphics/UI/SDL/Basic.hs b/Graphics/UI/SDL/Basic.hs
--- a/Graphics/UI/SDL/Basic.hs
+++ b/Graphics/UI/SDL/Basic.hs
@@ -18,24 +18,23 @@
 	-- * Error Handling
 	clearError,
 	getError,
-	-- setError,
+	setError,
 
 	-- * Log Handling
-	-- log,
-	-- logCritical,
-	-- logDebug,
-	-- logError,
+	log,
+	logCritical,
+	logDebug,
+	logError,
 	logGetOutputFunction,
 	logGetPriority,
-	-- logInfo,
-	-- logMessage,
-	-- logMessageV,
+	logInfo,
+	logMessage,
 	logResetPriorities,
 	logSetAllPriority,
 	logSetOutputFunction,
 	logSetPriority,
-	-- logVerbose,
-	-- logWarn,
+	logVerbose,
+	logWarn,
 
 	-- * Assertions
 	-- | Use Haskell's own assertion primitives rather than SDL's.
@@ -52,7 +51,7 @@
 import Foreign.Ptr
 import Graphics.UI.SDL.Enum
 import Graphics.UI.SDL.Types
-import Prelude hiding (init)
+import Prelude hiding (init, log)
 
 foreign import ccall "SDL.h SDL_Init" init :: Word32 -> IO CInt
 foreign import ccall "SDL.h SDL_InitSubSystem" initSubSystem :: Word32 -> IO CInt
@@ -70,9 +69,11 @@
 
 foreign import ccall "SDL.h SDL_ClearError" clearError :: IO ()
 foreign import ccall "SDL.h SDL_GetError" getError :: IO CString
+foreign import ccall "sdlhelper.c SDLHelper_SetError" setError :: CString -> IO CInt
 
 foreign import ccall "SDL.h SDL_LogGetOutputFunction" logGetOutputFunction :: Ptr LogOutputFunction -> Ptr (Ptr ()) -> IO ()
 foreign import ccall "SDL.h SDL_LogGetPriority" logGetPriority :: CInt -> IO LogPriority
+foreign import ccall "sdlhelper.c SDLHelper_LogMessage" logMessage :: CInt -> LogPriority -> CString -> IO ()
 foreign import ccall "SDL.h SDL_LogResetPriorities" logResetPriorities :: IO ()
 foreign import ccall "SDL.h SDL_LogSetAllPriority" logSetAllPriority :: LogPriority -> IO ()
 foreign import ccall "SDL.h SDL_LogSetOutputFunction" logSetOutputFunction :: LogOutputFunction -> Ptr () -> IO ()
@@ -81,3 +82,24 @@
 foreign import ccall "SDL.h SDL_GetRevision" getRevision :: IO CString
 foreign import ccall "SDL.h SDL_GetRevisionNumber" getRevisionNumber :: IO CInt
 foreign import ccall "SDL.h SDL_GetVersion" getVersion :: Ptr Version -> IO ()
+
+log :: CString -> IO ()
+log = logMessage logCategoryApplication logPriorityInfo
+
+logCritical :: CInt -> CString -> IO ()
+logCritical category = logMessage category logPriorityCritical
+
+logDebug :: CInt -> CString -> IO ()
+logDebug category = logMessage category logPriorityDebug
+
+logError :: CInt -> CString -> IO ()
+logError category = logMessage category logPriorityError
+
+logInfo :: CInt -> CString -> IO ()
+logInfo category = logMessage category logPriorityInfo
+
+logVerbose :: CInt -> CString -> IO ()
+logVerbose category = logMessage category logPriorityVerbose
+
+logWarn :: CInt -> CString -> IO ()
+logWarn category = logMessage category logPriorityWarn
diff --git a/Graphics/UI/SDL/Enum.hsc b/Graphics/UI/SDL/Enum.hsc
--- a/Graphics/UI/SDL/Enum.hsc
+++ b/Graphics/UI/SDL/Enum.hsc
@@ -385,6 +385,12 @@
 	systemCursorHand,
 	systemCursorNum,
 
+	-- * Thread Priority
+	ThreadPriority,
+	threadPriorityLow,
+	threadPriorityNormal,
+	threadPriorityHigh,
+
 	-- * Miscellaneous Enumerations
 	-- | These enumerations are not used directly by any SDL function, thus they have a polymorphic type.
 
@@ -443,17 +449,6 @@
 	eventTypeUserEvent,
 	eventTypeLastEvent,
 
-	-- ** OpenGL Profile
-	glProfileCore,
-	glProfileCompatibility,
-	glProfileES,
-
-	-- ** OpenGL Context Flag
-	glContextFlagDebug,
-	glContextFlagForwardCompatible,
-	glContextFlagRobustAccess,
-	glContextFlagResetIsolation,
-
 	-- ** Initialization Flag
 	initFlagTimer,
 	initFlagAudio,
@@ -476,6 +471,18 @@
 	joystickHatLeftUp,
 	joystickHatLeftDown,
 
+	-- ** Log Category
+	logCategoryApplication,
+	logCategoryError,
+	logCategoryAssert,
+	logCategorySystem,
+	logCategoryAudio,
+	logCategoryVideo,
+	logCategoryRender,
+	logCategoryInput,
+	logCategoryTest,
+	logCategoryCustom,
+
 	-- ** Message Box Flags
 	messageBoxFlagError,
 	messageBoxFlagWarning,
@@ -485,6 +492,55 @@
 	messageBoxButtonFlagReturnKeyDefault,
 	messageBoxButtonFlagEscapeKeyDefault,
 
+	-- ** OpenGL Profile
+	glProfileCore,
+	glProfileCompatibility,
+	glProfileES,
+
+	-- ** OpenGL Context Flag
+	glContextFlagDebug,
+	glContextFlagForwardCompatible,
+	glContextFlagRobustAccess,
+	glContextFlagResetIsolation,
+
+	-- ** Pixel Formats
+	pixelFormatUnknown,
+	pixelFormatIndex1LSB,
+	pixelFormatIndex1MSB,
+	pixelFormatIndex4LSB,
+	pixelFormatIndex4MSB,
+	pixelFormatIndex8,
+	pixelFormatRGB332,
+	pixelFormatRGB444,
+	pixelFormatRGB555,
+	pixelFormatBGR555,
+	pixelFormatARGB4444,
+	pixelFormatRGBA4444,
+	pixelFormatABGR4444,
+	pixelFormatBGRA4444,
+	pixelFormatARGB1555,
+	pixelFormatRGBA5551,
+	pixelFormatABGR1555,
+	pixelFormatBGRA5551,
+	pixelFormatRGB565,
+	pixelFormatBGR565,
+	pixelFormatRGB24,
+	pixelFormatBGR24,
+	pixelFormatRGB888,
+	pixelFormatRGBX8888,
+	pixelFormatBGR888,
+	pixelFormatBGRX8888,
+	pixelFormatARGB8888,
+	pixelFormatRGBA8888,
+	pixelFormatABGR8888,
+	pixelFormatBGRA8888,
+	pixelFormatARGB2101010,
+	pixelFormatYV12,
+	pixelFormatIYUV,
+	pixelFormatYUY2,
+	pixelFormatUYVY,
+	pixelFormatYVYU,
+
 	-- ** Renderer Flags
 	rendererFlagSoftware,
 	rendererFlagAccelerated,
@@ -1286,6 +1342,16 @@
 systemCursorHand = (#const SDL_SYSTEM_CURSOR_HAND)
 systemCursorNum = (#const SDL_NUM_SYSTEM_CURSORS)
 
+type ThreadPriority = (#type SDL_ThreadPriority)
+
+threadPriorityLow :: ThreadPriority
+threadPriorityNormal :: ThreadPriority
+threadPriorityHigh :: ThreadPriority
+
+threadPriorityLow = (#const SDL_THREAD_PRIORITY_LOW)
+threadPriorityNormal = (#const SDL_THREAD_PRIORITY_NORMAL)
+threadPriorityHigh = (#const SDL_THREAD_PRIORITY_HIGH)
+
 buttonLeft :: (Num a) => a
 buttonMiddle :: (Num a) => a
 buttonRight :: (Num a) => a
@@ -1392,24 +1458,6 @@
 eventTypeUserEvent = (#const SDL_USEREVENT)
 eventTypeLastEvent = (#const SDL_LASTEVENT)
 
-glProfileCore :: (Num a) => a
-glProfileCompatibility :: (Num a) => a
-glProfileES :: (Num a) => a
-
-glProfileCore = (#const SDL_GL_CONTEXT_PROFILE_CORE)
-glProfileCompatibility = (#const SDL_GL_CONTEXT_PROFILE_COMPATIBILITY)
-glProfileES = (#const SDL_GL_CONTEXT_PROFILE_ES)
-
-glContextFlagDebug :: (Num a) => a
-glContextFlagForwardCompatible :: (Num a) => a
-glContextFlagRobustAccess :: (Num a) => a
-glContextFlagResetIsolation :: (Num a) => a
-
-glContextFlagDebug = (#const SDL_GL_CONTEXT_DEBUG_FLAG)
-glContextFlagForwardCompatible = (#const SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG)
-glContextFlagRobustAccess = (#const SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG)
-glContextFlagResetIsolation = (#const SDL_GL_CONTEXT_RESET_ISOLATION_FLAG)
-
 initFlagTimer :: (Num a) => a
 initFlagAudio :: (Num a) => a
 initFlagVideo :: (Num a) => a
@@ -1450,6 +1498,28 @@
 joystickHatLeftUp = (#const SDL_HAT_LEFTUP)
 joystickHatLeftDown = (#const SDL_HAT_LEFTDOWN)
 
+logCategoryApplication :: (Num a) => a
+logCategoryError :: (Num a) => a
+logCategoryAssert :: (Num a) => a
+logCategorySystem :: (Num a) => a
+logCategoryAudio :: (Num a) => a
+logCategoryVideo :: (Num a) => a
+logCategoryRender :: (Num a) => a
+logCategoryInput :: (Num a) => a
+logCategoryTest :: (Num a) => a
+logCategoryCustom :: (Num a) => a
+
+logCategoryApplication = (#const SDL_LOG_CATEGORY_APPLICATION)
+logCategoryError = (#const SDL_LOG_CATEGORY_ERROR)
+logCategoryAssert = (#const SDL_LOG_CATEGORY_ASSERT)
+logCategorySystem = (#const SDL_LOG_CATEGORY_SYSTEM)
+logCategoryAudio = (#const SDL_LOG_CATEGORY_AUDIO)
+logCategoryVideo = (#const SDL_LOG_CATEGORY_VIDEO)
+logCategoryRender = (#const SDL_LOG_CATEGORY_RENDER)
+logCategoryInput = (#const SDL_LOG_CATEGORY_INPUT)
+logCategoryTest = (#const SDL_LOG_CATEGORY_TEST)
+logCategoryCustom = (#const SDL_LOG_CATEGORY_CUSTOM)
+
 messageBoxFlagError :: (Num a) => a
 messageBoxFlagWarning :: (Num a) => a
 messageBoxFlagInformation :: (Num a) => a
@@ -1463,6 +1533,98 @@
 
 messageBoxButtonFlagReturnKeyDefault = (#const SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT)
 messageBoxButtonFlagEscapeKeyDefault = (#const SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT)
+
+glProfileCore :: (Num a) => a
+glProfileCompatibility :: (Num a) => a
+glProfileES :: (Num a) => a
+
+glProfileCore = (#const SDL_GL_CONTEXT_PROFILE_CORE)
+glProfileCompatibility = (#const SDL_GL_CONTEXT_PROFILE_COMPATIBILITY)
+glProfileES = (#const SDL_GL_CONTEXT_PROFILE_ES)
+
+glContextFlagDebug :: (Num a) => a
+glContextFlagForwardCompatible :: (Num a) => a
+glContextFlagRobustAccess :: (Num a) => a
+glContextFlagResetIsolation :: (Num a) => a
+
+glContextFlagDebug = (#const SDL_GL_CONTEXT_DEBUG_FLAG)
+glContextFlagForwardCompatible = (#const SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG)
+glContextFlagRobustAccess = (#const SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG)
+glContextFlagResetIsolation = (#const SDL_GL_CONTEXT_RESET_ISOLATION_FLAG)
+
+pixelFormatUnknown :: (Num a) => a
+pixelFormatIndex1LSB :: (Num a) => a
+pixelFormatIndex1MSB :: (Num a) => a
+pixelFormatIndex4LSB :: (Num a) => a
+pixelFormatIndex4MSB :: (Num a) => a
+pixelFormatIndex8 :: (Num a) => a
+pixelFormatRGB332 :: (Num a) => a
+pixelFormatRGB444 :: (Num a) => a
+pixelFormatRGB555 :: (Num a) => a
+pixelFormatBGR555 :: (Num a) => a
+pixelFormatARGB4444 :: (Num a) => a
+pixelFormatRGBA4444 :: (Num a) => a
+pixelFormatABGR4444 :: (Num a) => a
+pixelFormatBGRA4444 :: (Num a) => a
+pixelFormatARGB1555 :: (Num a) => a
+pixelFormatRGBA5551 :: (Num a) => a
+pixelFormatABGR1555 :: (Num a) => a
+pixelFormatBGRA5551 :: (Num a) => a
+pixelFormatRGB565 :: (Num a) => a
+pixelFormatBGR565 :: (Num a) => a
+pixelFormatRGB24 :: (Num a) => a
+pixelFormatBGR24 :: (Num a) => a
+pixelFormatRGB888 :: (Num a) => a
+pixelFormatRGBX8888 :: (Num a) => a
+pixelFormatBGR888 :: (Num a) => a
+pixelFormatBGRX8888 :: (Num a) => a
+pixelFormatARGB8888 :: (Num a) => a
+pixelFormatRGBA8888 :: (Num a) => a
+pixelFormatABGR8888 :: (Num a) => a
+pixelFormatBGRA8888 :: (Num a) => a
+pixelFormatARGB2101010 :: (Num a) => a
+pixelFormatYV12 :: (Num a) => a
+pixelFormatIYUV :: (Num a) => a
+pixelFormatYUY2 :: (Num a) => a
+pixelFormatUYVY :: (Num a) => a
+pixelFormatYVYU :: (Num a) => a
+
+pixelFormatUnknown = (#const SDL_PIXELFORMAT_UNKNOWN)
+pixelFormatIndex1LSB = (#const SDL_PIXELFORMAT_INDEX1LSB)
+pixelFormatIndex1MSB = (#const SDL_PIXELFORMAT_INDEX1MSB)
+pixelFormatIndex4LSB = (#const SDL_PIXELFORMAT_INDEX4LSB)
+pixelFormatIndex4MSB = (#const SDL_PIXELFORMAT_INDEX4MSB)
+pixelFormatIndex8 = (#const SDL_PIXELFORMAT_INDEX8)
+pixelFormatRGB332 = (#const SDL_PIXELFORMAT_RGB332)
+pixelFormatRGB444 = (#const SDL_PIXELFORMAT_RGB444)
+pixelFormatRGB555 = (#const SDL_PIXELFORMAT_RGB555)
+pixelFormatBGR555 = (#const SDL_PIXELFORMAT_BGR555)
+pixelFormatARGB4444 = (#const SDL_PIXELFORMAT_ARGB4444)
+pixelFormatRGBA4444 = (#const SDL_PIXELFORMAT_RGBA4444)
+pixelFormatABGR4444 = (#const SDL_PIXELFORMAT_ABGR4444)
+pixelFormatBGRA4444 = (#const SDL_PIXELFORMAT_BGRA4444)
+pixelFormatARGB1555 = (#const SDL_PIXELFORMAT_ARGB1555)
+pixelFormatRGBA5551 = (#const SDL_PIXELFORMAT_RGBA5551)
+pixelFormatABGR1555 = (#const SDL_PIXELFORMAT_ABGR1555)
+pixelFormatBGRA5551 = (#const SDL_PIXELFORMAT_BGRA5551)
+pixelFormatRGB565 = (#const SDL_PIXELFORMAT_RGB565)
+pixelFormatBGR565 = (#const SDL_PIXELFORMAT_BGR565)
+pixelFormatRGB24 = (#const SDL_PIXELFORMAT_RGB24)
+pixelFormatBGR24 = (#const SDL_PIXELFORMAT_BGR24)
+pixelFormatRGB888 = (#const SDL_PIXELFORMAT_RGB888)
+pixelFormatRGBX8888 = (#const SDL_PIXELFORMAT_RGBX8888)
+pixelFormatBGR888 = (#const SDL_PIXELFORMAT_BGR888)
+pixelFormatBGRX8888 = (#const SDL_PIXELFORMAT_BGRX8888)
+pixelFormatARGB8888 = (#const SDL_PIXELFORMAT_ARGB8888)
+pixelFormatRGBA8888 = (#const SDL_PIXELFORMAT_RGBA8888)
+pixelFormatABGR8888 = (#const SDL_PIXELFORMAT_ABGR8888)
+pixelFormatBGRA8888 = (#const SDL_PIXELFORMAT_BGRA8888)
+pixelFormatARGB2101010 = (#const SDL_PIXELFORMAT_ARGB2101010)
+pixelFormatYV12 = (#const SDL_PIXELFORMAT_YV12)
+pixelFormatIYUV = (#const SDL_PIXELFORMAT_IYUV)
+pixelFormatYUY2 = (#const SDL_PIXELFORMAT_YUY2)
+pixelFormatUYVY = (#const SDL_PIXELFORMAT_UYVY)
+pixelFormatYVYU = (#const SDL_PIXELFORMAT_YVYU)
 
 rendererFlagSoftware :: (Num a) => a
 rendererFlagAccelerated :: (Num a) => a
diff --git a/Graphics/UI/SDL/Filesystem.hs b/Graphics/UI/SDL/Filesystem.hs
--- a/Graphics/UI/SDL/Filesystem.hs
+++ b/Graphics/UI/SDL/Filesystem.hs
@@ -36,8 +36,8 @@
 import Foreign.Ptr
 import Graphics.UI.SDL.Types
 
-foreign import ccall "SDL.H SDL_GetBasePath" getBasePath :: IO CString
-foreign import ccall "SDL.H SDL_GetPrefPath" getPrefPath :: CString -> CString -> IO CString
+foreign import ccall "SDL.h SDL_GetBasePath" getBasePath :: IO CString
+foreign import ccall "SDL.h SDL_GetPrefPath" getPrefPath :: CString -> CString -> IO CString
 
 foreign import ccall "SDL.h SDL_AllocRW" allocRW :: IO (Ptr RWops)
 foreign import ccall "SDL.h SDL_FreeRW" freeRW :: Ptr RWops -> IO ()
diff --git a/Graphics/UI/SDL/Platform.hs b/Graphics/UI/SDL/Platform.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/UI/SDL/Platform.hs
@@ -0,0 +1,8 @@
+module Graphics.UI.SDL.Platform (
+	-- * Platform Detection
+	getPlatform
+) where
+
+import Foreign.C.String
+
+foreign import ccall "SDL.h SDL_GetPlatform" getPlatform :: IO CString
diff --git a/Graphics/UI/SDL/Thread.hs b/Graphics/UI/SDL/Thread.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/UI/SDL/Thread.hs
@@ -0,0 +1,103 @@
+module Graphics.UI.SDL.Thread (
+	-- * Thread Management
+	createThread,
+	detachThread,
+	getThreadID,
+	getThreadName,
+	setThreadPriority,
+	tlsCreate,
+	tlsGet,
+	tlsSet,
+	threadID,
+	waitThread,
+
+	-- * Thread Synchronization Primitives
+	condBroadcast,
+	condSignal,
+	condWait,
+	condWaitTimeout,
+	createCond,
+	createMutex,
+	createSemaphore,
+	destroyCond,
+	destroyMutex,
+	destroySemaphore,
+	lockMutex,
+	semPost,
+	semTryWait,
+	semValue,
+	semWait,
+	semWaitTimeout,
+	tryLockMutex,
+	unlockMutex,
+
+	-- * Atomic Operations
+	atomicAdd,
+	atomicCAS,
+	atomicCASPtr,
+	atomicDecRef,
+	atomicGet,
+	atomicGetPtr,
+	atomicIncRef,
+	atomicLock,
+	atomicSet,
+	atomicSetPtr,
+	atomicTryLock,
+	atomicUnlock
+) where
+
+import Data.Word
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.Ptr
+import Graphics.UI.SDL.Enum
+import Graphics.UI.SDL.Types
+
+foreign import ccall "SDL.h CreateThread" createThread :: ThreadFunction -> CString -> IO (Ptr ())
+foreign import ccall "SDL.h DetachThread" detachThread :: Ptr Thread -> IO ()
+foreign import ccall "SDL.h GetThreadID" getThreadID :: Ptr Thread -> IO ThreadID
+foreign import ccall "SDL.h GetThreadName" getThreadName :: Ptr Thread -> IO CString
+foreign import ccall "SDL.h SetThreadPriority" setThreadPriority :: ThreadPriority -> IO CInt
+foreign import ccall "SDL.h TLSCreate" tlsCreate :: IO TLSID
+foreign import ccall "SDL.h TLSGet" tlsGet :: TLSID -> IO (Ptr ())
+foreign import ccall "SDL.h TLSSet" tlsSet :: TLSID -> Ptr () -> FunPtr (Ptr () -> IO ()) -> IO CInt
+foreign import ccall "SDL.h ThreadID" threadID :: IO ThreadID
+foreign import ccall "SDL.h WaitThread" waitThread :: Ptr Thread -> Ptr CInt -> IO ()
+
+foreign import ccall "SDL.h CondBroadcast" condBroadcast :: Ptr Cond -> IO CInt
+foreign import ccall "SDL.h CondSignal" condSignal :: Ptr Cond -> IO CInt
+foreign import ccall "SDL.h CondWait" condWait :: Ptr Cond -> Ptr Mutex -> IO CInt
+foreign import ccall "SDL.h CondWaitTimeout" condWaitTimeout :: Ptr Cond -> Ptr Mutex -> Word32 -> IO CInt
+foreign import ccall "SDL.h CreateCond" createCond :: IO (Ptr Cond)
+foreign import ccall "SDL.h CreateMutex" createMutex :: IO (Ptr Mutex)
+foreign import ccall "SDL.h CreateSemaphore" createSemaphore :: Word32 -> IO (Ptr Sem)
+foreign import ccall "SDL.h DestroyCond" destroyCond :: Ptr Cond -> IO ()
+foreign import ccall "SDL.h DestroyMutex" destroyMutex :: Ptr Mutex -> IO ()
+foreign import ccall "SDL.h DestroySemaphore" destroySemaphore :: Ptr Sem -> IO ()
+foreign import ccall "SDL.h LockMutex" lockMutex :: Ptr Mutex -> IO CInt
+foreign import ccall "SDL.h SemPost" semPost :: Ptr Sem -> IO CInt
+foreign import ccall "SDL.h SemTryWait" semTryWait :: Ptr Sem -> IO CInt
+foreign import ccall "SDL.h SemValue" semValue :: Ptr Sem -> IO Word32
+foreign import ccall "SDL.h SemWait" semWait :: Ptr Sem -> IO CInt
+foreign import ccall "SDL.h SemWaitTimeout" semWaitTimeout :: Ptr Sem -> Word32 -> IO CInt
+foreign import ccall "SDL.h TryLockMutex" tryLockMutex :: Ptr Mutex -> IO CInt
+foreign import ccall "SDL.h UnlockMutex" unlockMutex :: Ptr Mutex -> IO CInt
+
+foreign import ccall "SDL.h AtomicAdd" atomicAdd :: Ptr Atomic -> CInt -> IO CInt
+foreign import ccall "SDL.h AtomicCAS" atomicCAS :: Ptr Atomic -> CInt -> CInt -> IO Bool
+foreign import ccall "SDL.h AtomicCASPtr" atomicCASPtr :: Ptr (Ptr ()) -> Ptr () -> Ptr () -> IO Bool
+foreign import ccall "SDL.h AtomicGet" atomicGet :: Ptr Atomic -> IO CInt
+foreign import ccall "SDL.h AtomicGetPtr" atomicGetPtr :: Ptr (Ptr ()) -> IO (Ptr ())
+foreign import ccall "SDL.h AtomicLock" atomicLock :: Ptr SpinLock -> IO ()
+foreign import ccall "SDL.h AtomicSet" atomicSet :: Ptr Atomic -> CInt -> IO CInt
+foreign import ccall "SDL.h AtomicSetPtr" atomicSetPtr :: Ptr (Ptr ()) -> Ptr () -> IO (Ptr ())
+foreign import ccall "SDL.h AtomicTryLock" atomicTryLock :: Ptr SpinLock -> IO Bool
+foreign import ccall "SDL.h AtomicUnlock" atomicUnlock :: Ptr SpinLock -> IO ()
+
+atomicDecRef :: Ptr Atomic -> IO Bool
+atomicDecRef a = do
+	old <- atomicAdd a (-1)
+	return $ old == 1
+
+atomicIncRef :: Ptr Atomic -> IO CInt
+atomicIncRef a = atomicAdd a 1
diff --git a/Graphics/UI/SDL/Types.hsc b/Graphics/UI/SDL/Types.hsc
--- a/Graphics/UI/SDL/Types.hsc
+++ b/Graphics/UI/SDL/Types.hsc
@@ -3,6 +3,7 @@
 	AudioCallback,
 	AudioDeviceID,
 	AudioFormat,
+	Cond,
 	Cursor,
 	EventFilter,
 	FingerID,
@@ -15,15 +16,24 @@
 	JoystickID,
 	Keycode,
 	LogOutputFunction,
+	Mutex,
 	Renderer,
+	Sem,
+	SpinLock,
+	SysWMinfo,
 	SysWMmsg,
 	Texture,
+	Thread,
+	ThreadFunction,
+	ThreadID,
 	TimerCallback,
 	TimerID,
+	TLSID,
 	TouchID,
 	Window,
 
 	-- * Data Structures
+	Atomic(..),
 	AudioCVT(..),
 	AudioSpec(..),
 	Color(..),
@@ -63,6 +73,7 @@
 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
@@ -75,13 +86,34 @@
 type JoystickID = Int32
 type Keycode = 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
diff --git a/Graphics/UI/SDL/Video.hs b/Graphics/UI/SDL/Video.hs
--- a/Graphics/UI/SDL/Video.hs
+++ b/Graphics/UI/SDL/Video.hs
@@ -51,7 +51,6 @@
 	getWindowSize,
 	getWindowSurface,
 	getWindowTitle,
-	-- getWindowWMInfo,
 	hideWindow,
 	isScreenSaverEnabled,
 	maximizeWindow,
@@ -187,7 +186,7 @@
 	unlockSurface,
 
 	-- * Platform-specific Window Management
-	-- getWindowWMInfo,
+	getWindowWMInfo,
 
 	-- * Clipboard Handling
 	getClipboardText,
@@ -368,12 +367,10 @@
 foreign import ccall "SDL.h SDL_GetSurfaceAlphaMod" getSurfaceAlphaMod :: Ptr Surface -> Ptr Word8 -> IO CInt
 foreign import ccall "SDL.h SDL_GetSurfaceBlendMode" getSurfaceBlendMode :: Ptr Surface -> BlendMode -> IO CInt
 foreign import ccall "SDL.h SDL_GetSurfaceColorMod" getSurfaceColorMod :: Ptr Surface -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt
--- foreign import ccall "SDL.h SDL_LoadBMP" loadBMP :: CString -> IO (Ptr Surface)
 foreign import ccall "SDL.h SDL_LoadBMP_RW" loadBMP_RW :: Ptr RWops -> CInt -> IO (Ptr Surface)
 foreign import ccall "SDL.h SDL_LockSurface" lockSurface :: Ptr Surface -> IO CInt
 foreign import ccall "SDL.h SDL_LowerBlit" lowerBlit :: Ptr Surface -> Ptr Rect -> Ptr Surface -> Ptr Rect -> IO CInt
 foreign import ccall "SDL.h SDL_LowerBlitScaled" lowerBlitScaled :: Ptr Surface -> Ptr Rect -> Ptr Surface -> Ptr Rect -> IO CInt
--- foreign import ccall "SDL.h SDL_SaveBMP" saveBMP :: Ptr Surface -> CString -> IO CInt
 foreign import ccall "SDL.h SDL_SaveBMP_RW" saveBMP_RW :: Ptr Surface -> Ptr RWops -> CInt -> IO CInt
 foreign import ccall "SDL.h SDL_SetClipRect" setClipRect :: Ptr Surface -> Ptr Rect -> IO Bool
 foreign import ccall "SDL.h SDL_SetColorKey" setColorKey :: Ptr Surface -> CInt -> Word32 -> IO CInt
@@ -383,6 +380,8 @@
 foreign import ccall "SDL.h SDL_SetSurfacePalette" setSurfacePalette :: Ptr Surface -> Ptr Palette -> IO CInt
 foreign import ccall "SDL.h SDL_SetSurfaceRLE" setSurfaceRLE :: Ptr Surface -> CInt -> IO CInt
 foreign import ccall "SDL.h SDL_UnlockSurface" unlockSurface :: Ptr Surface -> IO ()
+
+foreign import ccall "SDL.h SDL_GetWindowWMInfo" getWindowWMInfo :: Window -> SysWMinfo -> IO Bool
 
 foreign import ccall "SDL.h SDL_GetClipboardText" getClipboardText :: IO CString
 foreign import ccall "SDL.h SDL_HasClipboardText" hasClipboardText :: IO Bool
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2013, Gabríel Arthúr Pétursson
+Copyright (c) 2013, 2014  Gabríel Arthúr Pétursson
 
 All rights reserved.
 
diff --git a/cbits/sdlhelper.c b/cbits/sdlhelper.c
--- a/cbits/sdlhelper.c
+++ b/cbits/sdlhelper.c
@@ -1,67 +1,77 @@
 #include <string.h>
 #include "sdlhelper.h"
 
-void SDLHelper_JoystickGetDeviceGUID(int device_index, SDL_JoystickGUID *guid)
+void SDLHelper_JoystickGetDeviceGUID (int device_index, SDL_JoystickGUID *guid)
 {
-	SDL_JoystickGUID t = SDL_JoystickGetDeviceGUID(device_index);
-	memcpy(guid, &t, sizeof(*guid));
+	SDL_JoystickGUID t = SDL_JoystickGetDeviceGUID (device_index);
+	memcpy (guid, &t, sizeof (*guid));
 }
 
-void SDLHelper_JoystickGetGUID(SDL_Joystick *joystick, SDL_JoystickGUID *guid)
+void SDLHelper_JoystickGetGUID (SDL_Joystick *joystick, SDL_JoystickGUID *guid)
 {
-	SDL_JoystickGUID t = SDL_JoystickGetGUID(joystick);
-	memcpy(guid, &t, sizeof(*guid));
+	SDL_JoystickGUID t = SDL_JoystickGetGUID (joystick);
+	memcpy (guid, &t, sizeof (*guid));
 }
 
-void SDLHelper_JoystickGetGUIDFromString(const char *pchGUID, SDL_JoystickGUID *guid)
+void SDLHelper_JoystickGetGUIDFromString (const char *pchGUID, SDL_JoystickGUID *guid)
 {
-	SDL_JoystickGUID t = SDL_JoystickGetGUIDFromString(pchGUID);
-	memcpy(guid, &t, sizeof(*guid));
+	SDL_JoystickGUID t = SDL_JoystickGetGUIDFromString (pchGUID);
+	memcpy (guid, &t, sizeof (*guid));
 }
 
-void SDLHelper_JoystickGetGUIDString(const SDL_JoystickGUID *guid, char *gszGUID, int cbGUID)
+void SDLHelper_JoystickGetGUIDString (const SDL_JoystickGUID *guid, char *gszGUID, int cbGUID)
 {
-	SDL_JoystickGetGUIDString(*guid, gszGUID, cbGUID);
+	SDL_JoystickGetGUIDString (*guid, gszGUID, cbGUID);
 }
 
-void SDLHelper_GameControllerGetBindForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, SDL_GameControllerButtonBind *bind)
+void SDLHelper_GameControllerGetBindForAxis (SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, SDL_GameControllerButtonBind *bind)
 {
-	SDL_GameControllerButtonBind t = SDL_GameControllerGetBindForAxis(gamecontroller, axis);
-	memcpy(bind, &t, sizeof(*bind));
+	SDL_GameControllerButtonBind t = SDL_GameControllerGetBindForAxis (gamecontroller, axis);
+	memcpy (bind, &t, sizeof (*bind));
 }
 
-void SDLHelper_GameControllerGetBindForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button, SDL_GameControllerButtonBind *bind)
+void SDLHelper_GameControllerGetBindForButton (SDL_GameController *gamecontroller, SDL_GameControllerButton button, SDL_GameControllerButtonBind *bind)
 {
-	SDL_GameControllerButtonBind t = SDL_GameControllerGetBindForButton(gamecontroller, button);
-	memcpy(bind, &t, sizeof(*bind));
+	SDL_GameControllerButtonBind t = SDL_GameControllerGetBindForButton (gamecontroller, button);
+	memcpy (bind, &t, sizeof (*bind));
 }
 
-char *SDLHelper_GameControllerMappingForGUID(const SDL_JoystickGUID *guid)
+char *SDLHelper_GameControllerMappingForGUID (const SDL_JoystickGUID *guid)
 {
-	return SDL_GameControllerMappingForGUID(*guid);
+	return SDL_GameControllerMappingForGUID (*guid);
 }
 
-int SDLHelper_RWclose(SDL_RWops *ctx)
+void SDLHelper_LogMessage (int category, SDL_LogPriority priority, const char *str)
 {
-	return SDL_RWclose(ctx);
+	SDL_LogMessage (category, priority, "%s", str);
 }
 
-size_t SDLHelper_RWread(SDL_RWops *ctx, void *ptr, size_t size, size_t maxnum)
+int SDLHelper_RWclose (SDL_RWops *ctx)
 {
-	return SDL_RWread(ctx, ptr, size, maxnum);
+	return SDL_RWclose (ctx);
 }
 
-Sint64 SDLHelper_RWseek(SDL_RWops *ctx, Sint64 offset, int whence)
+size_t SDLHelper_RWread (SDL_RWops *ctx, void *ptr, size_t size, size_t maxnum)
 {
-	return SDL_RWseek(ctx, offset, whence);
+	return SDL_RWread (ctx, ptr, size, maxnum);
 }
 
-Sint64 SDLHelper_RWtell(SDL_RWops *ctx)
+Sint64 SDLHelper_RWseek (SDL_RWops *ctx, Sint64 offset, int whence)
 {
-	return SDL_RWtell(ctx);
+	return SDL_RWseek (ctx, offset, whence);
 }
 
-size_t SDLHelper_RWwrite(SDL_RWops *ctx, const void *ptr, size_t size, size_t num)
+Sint64 SDLHelper_RWtell (SDL_RWops *ctx)
 {
-	return SDL_RWwrite(ctx, ptr, size, num);
+	return SDL_RWtell (ctx);
+}
+
+size_t SDLHelper_RWwrite (SDL_RWops *ctx, const void *ptr, size_t size, size_t num)
+{
+	return SDL_RWwrite (ctx, ptr, size, num);
+}
+
+int SDLHelper_SetError (const char *str)
+{
+	return SDL_SetError ("%s", str);
 }
diff --git a/include/sdlhelper.h b/include/sdlhelper.h
--- a/include/sdlhelper.h
+++ b/include/sdlhelper.h
@@ -4,19 +4,23 @@
 #include <stddef.h>
 #include "SDL.h"
 
-void SDLHelper_JoystickGetDeviceGUID(int device_index, SDL_JoystickGUID *guid);
-void SDLHelper_JoystickGetGUID(SDL_Joystick *joystick, SDL_JoystickGUID *guid);
-void SDLHelper_JoystickGetGUIDFromString(const char *pchGUID, SDL_JoystickGUID *guid);
-void SDLHelper_JoystickGetGUIDString(const SDL_JoystickGUID *guid, char *gszGUID, int cbGUID);
+void SDLHelper_JoystickGetDeviceGUID (int device_index, SDL_JoystickGUID *guid);
+void SDLHelper_JoystickGetGUID (SDL_Joystick *joystick, SDL_JoystickGUID *guid);
+void SDLHelper_JoystickGetGUIDFromString (const char *pchGUID, SDL_JoystickGUID *guid);
+void SDLHelper_JoystickGetGUIDString (const SDL_JoystickGUID *guid, char *gszGUID, int cbGUID);
 
-void SDLHelper_GameControllerGetBindForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, SDL_GameControllerButtonBind *bind);
-void SDLHelper_GameControllerGetBindForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button, SDL_GameControllerButtonBind *bind);
-char *SDLHelper_GameControllerMappingForGUID(const SDL_JoystickGUID *guid);
+void SDLHelper_GameControllerGetBindForAxis (SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, SDL_GameControllerButtonBind *bind);
+void SDLHelper_GameControllerGetBindForButton (SDL_GameController *gamecontroller, SDL_GameControllerButton button, SDL_GameControllerButtonBind *bind);
+char *SDLHelper_GameControllerMappingForGUID (const SDL_JoystickGUID *guid);
 
-int SDLHelper_RWclose(SDL_RWops *ctx);
-size_t SDLHelper_RWread(SDL_RWops *ctx, void *ptr, size_t size, size_t maxnum);
-Sint64 SDLHelper_RWseek(SDL_RWops *ctx, Sint64 offset, int whence);
-Sint64 SDLHelper_RWtell(SDL_RWops *ctx);
-size_t SDLHelper_RWwrite(SDL_RWops *ctx, const void *ptr, size_t size, size_t num);
+void SDLHelper_LogMessage (int category, SDL_LogPriority priority, const char *str);
+
+int SDLHelper_RWclose (SDL_RWops *ctx);
+size_t SDLHelper_RWread (SDL_RWops *ctx, void *ptr, size_t size, size_t maxnum);
+Sint64 SDLHelper_RWseek (SDL_RWops *ctx, Sint64 offset, int whence);
+Sint64 SDLHelper_RWtell (SDL_RWops *ctx);
+size_t SDLHelper_RWwrite (SDL_RWops *ctx, const void *ptr, size_t size, size_t num);
+
+int SDLHelper_SetError(const char *str);
 
 #endif
diff --git a/sdl2.cabal b/sdl2.cabal
--- a/sdl2.cabal
+++ b/sdl2.cabal
@@ -1,6 +1,6 @@
 name:                sdl2
-version:             1.1.0
-synopsis:            Bindings to SDL2
+version:             1.1.1
+synopsis:            Low-level bindings to SDL2
 description:         Low-level bindings to the SDL2 library, version 2.0.3.
 license:             BSD3
 license-file:        LICENSE
@@ -26,7 +26,9 @@
     Graphics.UI.SDL.Event
     Graphics.UI.SDL.Filesystem
     Graphics.UI.SDL.Haptic
+    Graphics.UI.SDL.Platform
     Graphics.UI.SDL.Power
+    Graphics.UI.SDL.Thread
     Graphics.UI.SDL.Timer
     Graphics.UI.SDL.Types
     Graphics.UI.SDL.Video
