{-# LANGUAGE CPP #-} {-# OPTIONS_HADDOCK hide #-} -- GIMP Toolkit (GTK) FFI extras and version dependencies -- -- Author : Axel Simon -- -- Created: 22 June 2001 -- -- Copyright (C) 1999-2005 Axel Simon -- -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Lesser General Public License for more details. -- -- #hide -- | -- -- This module serves as an impedance matcher for different compiler -- versions. It also adds a few FFI utility functions. -- module System.Glib.FFI ( with, nullForeignPtr, maybeNull, newForeignPtr, withForeignPtrs, module Foreign, module Foreign.C ) where import System.IO.Unsafe (unsafePerformIO) -- We should almost certainly not be using the standard free function anywhere -- in the glib or gtk bindings, so we do not re-export it from this module. import Foreign.C import qualified Foreign hiding (free) import Foreign hiding (with, newForeignPtr, free #if (__GLASGOW_HASKELL__<606) , withObject #endif ) #if (__GLASGOW_HASKELL__>=610) import qualified Foreign.Concurrent #endif with :: (Storable a) => a -> (Ptr a -> IO b) -> IO b with = Foreign.with #if (__GLASGOW_HASKELL__>=610) newForeignPtr :: Ptr a -> FinalizerPtr a -> IO (ForeignPtr a) newForeignPtr p finalizer = Foreign.Concurrent.newForeignPtr p (mkFinalizer finalizer p) foreign import ccall "dynamic" mkFinalizer :: FinalizerPtr a -> Ptr a -> IO () #else newForeignPtr :: Ptr a -> FinalizerPtr a -> IO (ForeignPtr a) newForeignPtr = flip Foreign.newForeignPtr #endif nullForeignPtr :: ForeignPtr a nullForeignPtr = unsafePerformIO $ newForeignPtr_ nullPtr -- This is useful when it comes to marshaling lists of GObjects -- withForeignPtrs :: [ForeignPtr a] -> ([Ptr a] -> IO b) -> IO b withForeignPtrs fptrs body = do result <- body (map unsafeForeignPtrToPtr fptrs) mapM_ touchForeignPtr fptrs return result -- A marshaling utility function that is used by the code produced by the code -- generator to marshal return values that can be null maybeNull :: (IO (Ptr a) -> IO a) -> IO (Ptr a) -> IO (Maybe a) maybeNull marshal genPtr = do ptr <- genPtr if ptr == nullPtr then return Nothing else do result <- marshal (return ptr) return (Just result)