    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.UI.SDL.Video
    -- Copyright   :  (c) David Himmelstrup 2005
    -- License     :  BSD-like
    --
    -- Maintainer  :  lemmih@gmail.com
    -- Stability   :  provisional
    -- Portability :  portable
    --
    -----------------------------------------------------------------------------
    module Graphics.UI.SDL.RWOps
        ( fromFile
        , tryFromFile
        , free
        , with
        , mkFinalizedRW
        ) where

    import Foreign (Ptr, FunPtr,
    #if defined(__GLASGOW_HASKELL__)
      finalizeForeignPtr,
    #endif
      maybePeek, newForeignPtr)
    import Foreign.C (withCString, CString)

    import Control.Exception (bracket)

    import Graphics.UI.SDL.Types (RWops, RWopsStruct)
    import Graphics.UI.SDL.General (unwrapMaybe)

    with :: FilePath -> String -> (RWops -> IO a) -> IO a
    with :: forall a. FilePath -> FilePath -> (RWops -> IO a) -> IO a
    with FilePath
    path FilePath
    mode RWops -> IO a
    action
        = IO RWops -> (RWops -> IO ()) -> (RWops -> IO a) -> IO a
    forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
    bracket (FilePath -> FilePath -> IO RWops
    fromFile FilePath
    path FilePath
    mode)
                  (RWops -> IO ()
    free)
                  RWops -> IO a
    action

    -- extern DECLSPEC SDL_RWops * SDLCALL SDL_RWFromFile(const char *file, const char *mode);
    foreign import ccall unsafe "SDL_RWFromFile" rwFromFile :: CString -> CString -> IO (Ptr RWopsStruct)
    tryFromFile :: FilePath -> String -> IO (Maybe RWops)
    tryFromFile :: FilePath -> FilePath -> IO (Maybe RWops)
    tryFromFile FilePath
    filepath FilePath
    mode
        = FilePath -> (CString -> IO (Maybe RWops)) -> IO (Maybe RWops)
    forall a. FilePath -> (CString -> IO a) -> IO a
    withCString FilePath
    filepath ((CString -> IO (Maybe RWops)) -> IO (Maybe RWops))
    -> (CString -> IO (Maybe RWops)) -> IO (Maybe RWops)
    forall a b. (a -> b) -> a -> b
    $ \CString
    cPath ->
          FilePath -> (CString -> IO (Maybe RWops)) -> IO (Maybe RWops)
    forall a. FilePath -> (CString -> IO a) -> IO a
    withCString FilePath
    mode ((CString -> IO (Maybe RWops)) -> IO (Maybe RWops))
    -> (CString -> IO (Maybe RWops)) -> IO (Maybe RWops)
    forall a b. (a -> b) -> a -> b
    $ \CString
    cMode ->
          CString -> CString -> IO (Ptr RWopsStruct)
    rwFromFile CString
    cPath CString
    cMode IO (Ptr RWopsStruct)
    -> (Ptr RWopsStruct -> IO (Maybe RWops)) -> IO (Maybe RWops)
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (Ptr RWopsStruct -> IO RWops)
    -> Ptr RWopsStruct -> IO (Maybe RWops)
    forall a b. (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
    maybePeek Ptr RWopsStruct -> IO RWops
    mkFinalizedRW

    fromFile :: FilePath -> String -> IO RWops
    fromFile :: FilePath -> FilePath -> IO RWops
    fromFile FilePath
    filepath FilePath
    mode = FilePath -> IO (Maybe RWops) -> IO RWops
    forall a. FilePath -> IO (Maybe a) -> IO a
    unwrapMaybe FilePath
    "SDL_RWFromFile" (FilePath -> FilePath -> IO (Maybe RWops)
    tryFromFile FilePath
    filepath FilePath
    mode)

    -- extern DECLSPEC void SDLCALL SDL_FreeRW(SDL_RWops *area);
    foreign import ccall unsafe "&SDL_FreeRW" rwFreeFinal :: FunPtr (Ptr RWopsStruct -> IO ())
    mkFinalizedRW :: Ptr RWopsStruct -> IO RWops
    mkFinalizedRW :: Ptr RWopsStruct -> IO RWops
    mkFinalizedRW = FinalizerPtr RWopsStruct -> Ptr RWopsStruct -> IO RWops
    forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
    newForeignPtr FinalizerPtr RWopsStruct
    rwFreeFinal

    free :: RWops -> IO ()
    free :: RWops -> IO ()
    free =
    #if defined(__GLASGOW_HASKELL__)
      RWops -> IO ()
    forall a. ForeignPtr a -> IO ()
    finalizeForeignPtr
    #else
      const (return ())
    #endif

    {-
    foreign import ccall unsafe "SDL_FreeRW" rwFree :: Ptr RWopsStruct -> IO ()
    free :: RWops -> IO ()
    free rw = withForeignPtr rw rwFree
    -}