diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,12 @@
+2.1.1
+======
+
+* `SDL.Input.Mouse` new has a new API for fetching the location of the mouse. This
+  API gives you greater control over finding the mouse position with respect to the
+  various "modes" a mouse can be in. The old API still exists, but will be removed
+  at some point in the future.
+* `SDL.Raw` now has a binding to `SDL_free`.
+
 2.1.0
 =====
 
diff --git a/sdl2.cabal b/sdl2.cabal
--- a/sdl2.cabal
+++ b/sdl2.cabal
@@ -1,5 +1,5 @@
 name:                sdl2
-version:             2.1.0
+version:             2.1.1
 synopsis:            Both high- and low-level bindings to the SDL library (version 2.0.3).
 description:
   This package contains bindings to the SDL 2 library, in both high- and
diff --git a/src/SDL/Input/Mouse.hs b/src/SDL/Input/Mouse.hs
--- a/src/SDL/Input/Mouse.hs
+++ b/src/SDL/Input/Mouse.hs
@@ -7,15 +7,21 @@
 
 module SDL.Input.Mouse
   ( -- * Relative Mouse Mode
-    setRelativeMouseMode
-  , getRelativeMouseMode
+    LocationMode(..)
+  , setMouseLocationMode
+  , getMouseLocationMode
+  , setRelativeMouseMode --deprecated
+  , getRelativeMouseMode --deprecated
 
     -- * Mouse and Touch Input
   , MouseButton(..)
   , MouseDevice(..)
 
     -- * Mouse State
-  , getMouseLocation
+  , getModalMouseLocation
+  , getMouseLocation --deprecated
+  , getAbsoluteMouseLocation
+  , getRelativeMouseLocation
   , getMouseButtons
 
     -- * Warping the Mouse
@@ -61,23 +67,49 @@
 import Control.Applicative
 #endif
 
+data LocationMode = AbsoluteLocation | RelativeLocation deriving Eq
+
 -- | Sets the current relative mouse mode.
 --
 -- When relative mouse mode is enabled, cursor is hidden and mouse position
 -- will not change. However, you will be delivered relative mouse position
 -- change events.
---
--- Throws 'SDLException' on failure.
+setMouseLocationMode :: (Functor m, MonadIO m) => LocationMode -> m LocationMode
+setMouseLocationMode mode =
+  Raw.setRelativeMouseMode (mode == RelativeLocation) >> getMouseLocationMode
+
+-- | Check which mouse location mode is currently active.
+getMouseLocationMode :: MonadIO m => m LocationMode
+getMouseLocationMode = do
+  relativeMode <- Raw.getRelativeMouseMode
+  return $ if relativeMode then RelativeLocation else AbsoluteLocation
+
+-- | Return proper mouse location depending on mouse mode
+getModalMouseLocation :: MonadIO m => m (LocationMode, Point V2 CInt)
+getModalMouseLocation = do
+  mode <- getMouseLocationMode
+  location <- case mode of
+    RelativeLocation -> getRelativeMouseLocation
+    _ -> getAbsoluteMouseLocation
+  return (mode, location)
+
+-- deprecated
 setRelativeMouseMode :: (Functor m, MonadIO m) => Bool -> m ()
+{-# DEPRECATED setRelativeMouseMode "Use setMouseLocationMode instead" #-}
 setRelativeMouseMode enable =
-    -- relative mouse mode can fail if it's not supported
-    throwIfNeg_ "SDL.Input.Mouse" "SDL_SetRelativeMouseMode" $
-        Raw.setRelativeMouseMode enable
+  throwIfNeg_ "SDL.Input.Mouse" "SDL_SetRelativeMouseMode" $
+    Raw.setRelativeMouseMode enable
 
--- | Check if relative mouse mode is enabled.
+--deprecated
 getRelativeMouseMode :: MonadIO m => m Bool
+{-# DEPRECATED getRelativeMouseMode "Use getMouseLocationMode instead" #-}
 getRelativeMouseMode = Raw.getRelativeMouseMode
 
+--deprecated
+getMouseLocation :: MonadIO m => m (Point V2 CInt)
+{-# DEPRECATED getMouseLocation "Use getAbsoluteMouseLocation instead, or getModalMouseLocation to match future behavior." #-}
+getMouseLocation = getAbsoluteMouseLocation
+
 data MouseButton
   = ButtonLeft
   | ButtonMiddle
@@ -128,12 +160,21 @@
   getCursorVisible = (== 1) <$> Raw.showCursor (-1)
 
 -- | Retrieve the current location of the mouse, relative to the currently focused window.
-getMouseLocation :: MonadIO m => m (Point V2 CInt)
-getMouseLocation = liftIO $
+getAbsoluteMouseLocation :: MonadIO m => m (Point V2 CInt)
+getAbsoluteMouseLocation = liftIO $
   alloca $ \x ->
   alloca $ \y -> do
     _ <- Raw.getMouseState x y -- We don't deal with button states here
     P <$> (V2 <$> peek x <*> peek y)
+
+-- | Retrieve mouse motion
+getRelativeMouseLocation :: MonadIO m => m (Point V2 CInt)
+getRelativeMouseLocation = liftIO $
+  alloca $ \x ->
+  alloca $ \y -> do
+    _ <- Raw.getRelativeMouseState x y
+    P <$> (V2 <$> peek x <*> peek y)
+
 
 -- | Retrieve a mapping of which buttons are currently held down.
 getMouseButtons :: MonadIO m => m (MouseButton -> Bool)
diff --git a/src/SDL/Raw/Basic.hs b/src/SDL/Raw/Basic.hs
--- a/src/SDL/Raw/Basic.hs
+++ b/src/SDL/Raw/Basic.hs
@@ -7,6 +7,9 @@
   setMainReady,
   wasInit,
 
+  -- * Memory Management
+  free,
+
   -- * Configuration Variables
   addHintCallback,
   clearHints,
@@ -55,6 +58,8 @@
 foreign import ccall "SDL.h SDL_SetMainReady" setMainReadyFFI :: IO ()
 foreign import ccall "SDL.h SDL_WasInit" wasInitFFI :: InitFlag -> IO InitFlag
 
+foreign import ccall "SDL.h SDL_free" freeFFI :: Ptr () -> IO ()
+
 foreign import ccall "SDL.h SDL_AddHintCallback" addHintCallbackFFI :: CString -> HintCallback -> Ptr () -> IO ()
 foreign import ccall "SDL.h SDL_ClearHints" clearHintsFFI :: IO ()
 foreign import ccall "SDL.h SDL_DelHintCallback" delHintCallbackFFI :: CString -> HintCallback -> Ptr () -> IO ()
@@ -97,6 +102,10 @@
 wasInit :: MonadIO m => InitFlag -> m InitFlag
 wasInit v1 = liftIO $ wasInitFFI v1
 {-# INLINE wasInit #-}
+
+free :: MonadIO m => Ptr () -> m ()
+free v1 = liftIO $ freeFFI v1
+{-# INLINE free #-}
 
 addHintCallback :: MonadIO m => CString -> HintCallback -> Ptr () -> m ()
 addHintCallback v1 v2 v3 = liftIO $ addHintCallbackFFI v1 v2 v3
