{-# LANGUAGE ForeignFunctionInterface #-} module Graphics.QML.Internal.BindObj where import Graphics.QML.Internal.Types {#import Graphics.QML.Internal.BindPrim #} import Control.Exception (bracket) import Control.Monad (void) import Foreign.C.Types import Foreign.Marshal.Utils (fromBool, toBool) import Foreign.Ptr import Foreign.ForeignPtr import qualified Foreign.ForeignPtr.Unsafe as UnsafeFPtr import Foreign.StablePtr #include "hsqml.h" marshalStable :: a -> (Ptr () -> IO b) -> IO b marshalStable obj f = do sPtr <- newStablePtr obj res <- f $ castStablePtrToPtr sPtr return res fromStable :: Ptr () -> IO a fromStable = deRefStablePtr . castPtrToStablePtr {#fun unsafe hsqml_get_next_class_id as ^ {} -> `CInt' id #} foreign import ccall "wrapper" marshalFunc :: UniformFunc -> IO (FunPtr UniformFunc) {#pointer *HsQMLClassHandle as ^ foreign newtype #} foreign import ccall "hsqml.h &hsqml_finalise_class_handle" hsqmlFinaliseClassHandlePtr :: FunPtr (Ptr (HsQMLClassHandle) -> IO ()) newClassHandle :: Ptr HsQMLClassHandle -> IO (Maybe HsQMLClassHandle) newClassHandle p = if nullPtr == p then return Nothing else do fp <- newForeignPtr hsqmlFinaliseClassHandlePtr p return $ Just $ HsQMLClassHandle fp {#fun unsafe hsqml_create_class as ^ {id `Ptr CUInt', id `Ptr CUInt', id `Ptr CChar', marshalStable* `ClassInfo', id `Ptr (FunPtr UniformFunc)', id `Ptr (FunPtr UniformFunc)'} -> `Maybe HsQMLClassHandle' newClassHandle* #} withMaybeHsQMLObjectHandle :: Maybe HsQMLObjectHandle -> (Ptr HsQMLObjectHandle -> IO b) -> IO b withMaybeHsQMLObjectHandle (Just (HsQMLObjectHandle fp)) = withForeignPtr fp withMaybeHsQMLObjectHandle Nothing = \f -> f nullPtr {#pointer *HsQMLObjectHandle as ^ foreign newtype #} foreign import ccall "hsqml.h &hsqml_finalise_object_handle" hsqmlFinaliseObjectHandlePtr :: FunPtr (Ptr (HsQMLObjectHandle) -> IO ()) foreign import ccall "hsqml.h &hsqml_finalise_object_weak_handle" hsqmlFinaliseObjectWeakHandlePtr :: FunPtr (Ptr (HsQMLObjectHandle) -> IO ()) newObjectHandle :: Ptr HsQMLObjectHandle -> IO HsQMLObjectHandle newObjectHandle p = do fp <- newForeignPtr hsqmlFinaliseObjectHandlePtr p return $ HsQMLObjectHandle fp isNullObjectHandle :: HsQMLObjectHandle -> Bool isNullObjectHandle (HsQMLObjectHandle fp) = nullPtr == UnsafeFPtr.unsafeForeignPtrToPtr fp {#fun unsafe hsqml_create_object as ^ {marshalStable* `a', withHsQMLClassHandle* `HsQMLClassHandle'} -> `HsQMLObjectHandle' newObjectHandle* #} {#fun unsafe hsqml_object_set_active as ^ {withMaybeHsQMLObjectHandle* `Maybe HsQMLObjectHandle'} -> `Bool' toBool #} withActiveObject :: HsQMLObjectHandle -> IO () -> IO () withActiveObject hndl action = bracket (hsqmlObjectSetActive $ Just hndl) (\ok -> if ok then void $ hsqmlObjectSetActive Nothing else return ()) (\ok -> if ok then action else return ()) {#fun unsafe hsqml_object_get_hs_typerep as ^ {withHsQMLObjectHandle* `HsQMLObjectHandle'} -> `ClassInfo' fromStable* #} {#fun unsafe hsqml_object_get_hs_value as ^ {withHsQMLObjectHandle* `HsQMLObjectHandle'} -> `a' fromStable* #} {#fun unsafe hsqml_object_get_pointer as ^ {withHsQMLObjectHandle* `HsQMLObjectHandle'} -> `Ptr ()' id #} {#fun unsafe hsqml_object_get_jval as ^ {withHsQMLObjectHandle* `HsQMLObjectHandle'} -> `HsQMLJValHandle' id #} {#fun unsafe hsqml_get_object_from_pointer as ^ {id `Ptr ()'} -> `HsQMLObjectHandle' newObjectHandle* #} {#fun unsafe hsqml_get_object_from_jval as ^ {id `HsQMLJValHandle'} -> `HsQMLObjectHandle' newObjectHandle* #} {#fun unsafe hsqml_object_reference_handle as ^ {id `Ptr HsQMLObjectHandle', fromBool `Bool'} -> `()' #} copyObjectHandle :: HsQMLObjectHandle -> Bool -> IO HsQMLObjectHandle copyObjectHandle (HsQMLObjectHandle fp) weak = do withForeignPtr fp $ \p -> do hsqmlObjectReferenceHandle p weak fp' <- newForeignPtr final p return $ HsQMLObjectHandle fp' where final = if weak then hsqmlFinaliseObjectWeakHandlePtr else hsqmlFinaliseObjectHandlePtr {#fun hsqml_fire_signal as ^ {withHsQMLObjectHandle* `HsQMLObjectHandle', `Int', id `Ptr (Ptr ())'} -> `()' #} {#pointer *HsQMLObjFinaliserHandle as ^ foreign newtype #} foreign import ccall "hsqml.h &hsqml_finalise_obj_finaliser" hsqmlFinaliseObjFinaliserPtr :: FunPtr (Ptr HsQMLObjFinaliserHandle -> IO ()) type ObjFinaliserFunc = Ptr HsQMLObjectHandle -> IO () foreign import ccall "wrapper" marshalObjFinaliser :: ObjFinaliserFunc -> IO (FunPtr ObjFinaliserFunc) newObjFinaliserHandle :: Ptr HsQMLObjFinaliserHandle -> IO HsQMLObjFinaliserHandle newObjFinaliserHandle p = do fp <- newForeignPtr hsqmlFinaliseObjFinaliserPtr p return $ HsQMLObjFinaliserHandle fp {#fun unsafe hsqml_create_obj_finaliser as ^ {id `FunPtr ObjFinaliserFunc'} -> `HsQMLObjFinaliserHandle' newObjFinaliserHandle* #} {#fun unsafe hsqml_object_add_finaliser as ^ {withHsQMLObjectHandle* `HsQMLObjectHandle', withHsQMLObjFinaliserHandle* `HsQMLObjFinaliserHandle'} -> `()' #}