packages feed

haskell-gi-base 0.19 → 0.20

raw patch · 41 files changed

+4965/−4859 lines, 41 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.GI.Base.BasicTypes: instance ((TypeError ...), Data.GI.Base.BasicTypes.ForeignPtrNewtype a) => Data.GI.Base.BasicTypes.GObject a
- Data.GI.Base.BasicTypes: type ForeignPtrNewtype a = Coercible a (ForeignPtr ())
- Data.GI.Base.GParamSpec: refGParamSpec :: GParamSpec -> IO (Ptr GParamSpec)
- Data.GI.Base.GVariant: refGVariant :: GVariant -> IO (Ptr GVariant)
- Data.GI.Base.ManagedPtr: copyBoxed :: forall a. BoxedObject a => a -> IO (Ptr a)
- Data.GI.Base.ManagedPtr: refObject :: (GObject a, GObject b) => a -> IO (Ptr b)
+ Data.GI.Base.BasicTypes: ManagedPtr :: ForeignPtr a -> IORef Bool -> ManagedPtr a
+ Data.GI.Base.BasicTypes: [managedForeignPtr] :: ManagedPtr a -> ForeignPtr a
+ Data.GI.Base.BasicTypes: [managedPtrIsOwned] :: ManagedPtr a -> IORef Bool
+ Data.GI.Base.BasicTypes: data ManagedPtr a
+ Data.GI.Base.BasicTypes: instance ((TypeError ...), Data.GI.Base.BasicTypes.ManagedPtrNewtype a) => Data.GI.Base.BasicTypes.GObject a
+ Data.GI.Base.BasicTypes: type ManagedPtrNewtype a = Coercible a (ManagedPtr ())
+ Data.GI.Base.GParamSpec: disownGParamSpec :: GParamSpec -> IO (Ptr GParamSpec)
+ Data.GI.Base.GVariant: disownGVariant :: GVariant -> IO (Ptr GVariant)
+ Data.GI.Base.ManagedPtr: disownBoxed :: BoxedObject a => a -> IO (Ptr a)
+ Data.GI.Base.ManagedPtr: disownManagedPtr :: forall a. ManagedPtrNewtype a => a -> IO (Ptr a)
+ Data.GI.Base.ManagedPtr: disownObject :: GObject a => a -> IO (Ptr b)
+ Data.GI.Base.ManagedPtr: newManagedPtr' :: FinalizerPtr a -> Ptr a -> IO (ManagedPtr a)
- Data.GI.Base.Attributes: [::=] :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, tag ~ AttrSet, AttrOpAllowed tag info, (AttrSetTypeConstraint info) b) => AttrLabelProxy (attr :: Symbol) -> (obj -> b) -> AttrOp obj tag
+ Data.GI.Base.Attributes: [::=] :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, tag ~ AttrSet, AttrOpAllowed tag info obj, (AttrSetTypeConstraint info) b) => AttrLabelProxy (attr :: Symbol) -> (obj -> b) -> AttrOp obj tag
- Data.GI.Base.Attributes: [::~] :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, tag ~ AttrSet, AttrOpAllowed AttrSet info, AttrOpAllowed AttrGet info, (AttrSetTypeConstraint info) b, a ~ (AttrGetType info)) => AttrLabelProxy (attr :: Symbol) -> (obj -> a -> b) -> AttrOp obj tag
+ Data.GI.Base.Attributes: [::~] :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, tag ~ AttrSet, AttrOpAllowed AttrSet info obj, AttrOpAllowed AttrGet info obj, (AttrSetTypeConstraint info) b, a ~ (AttrGetType info)) => AttrLabelProxy (attr :: Symbol) -> (obj -> a -> b) -> AttrOp obj tag
- Data.GI.Base.Attributes: [:=>] :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed tag info, (AttrSetTypeConstraint info) b) => AttrLabelProxy (attr :: Symbol) -> IO b -> AttrOp obj tag
+ Data.GI.Base.Attributes: [:=>] :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed tag info obj, (AttrSetTypeConstraint info) b) => AttrLabelProxy (attr :: Symbol) -> IO b -> AttrOp obj tag
- Data.GI.Base.Attributes: [:=] :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed tag info, (AttrSetTypeConstraint info) b) => AttrLabelProxy (attr :: Symbol) -> b -> AttrOp obj tag
+ Data.GI.Base.Attributes: [:=] :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed tag info obj, (AttrSetTypeConstraint info) b) => AttrLabelProxy (attr :: Symbol) -> b -> AttrOp obj tag
- Data.GI.Base.Attributes: [:~>] :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, tag ~ AttrSet, AttrOpAllowed AttrSet info, AttrOpAllowed AttrGet info, (AttrSetTypeConstraint info) b, a ~ (AttrGetType info)) => AttrLabelProxy (attr :: Symbol) -> (a -> IO b) -> AttrOp obj tag
+ Data.GI.Base.Attributes: [:~>] :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, tag ~ AttrSet, AttrOpAllowed AttrSet info obj, AttrOpAllowed AttrGet info obj, (AttrSetTypeConstraint info) b, a ~ (AttrGetType info)) => AttrLabelProxy (attr :: Symbol) -> (a -> IO b) -> AttrOp obj tag
- Data.GI.Base.Attributes: [:~] :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, tag ~ AttrSet, AttrOpAllowed AttrSet info, AttrOpAllowed AttrGet info, (AttrSetTypeConstraint info) b, a ~ (AttrGetType info)) => AttrLabelProxy (attr :: Symbol) -> (a -> b) -> AttrOp obj tag
+ Data.GI.Base.Attributes: [:~] :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, tag ~ AttrSet, AttrOpAllowed AttrSet info obj, AttrOpAllowed AttrGet info obj, (AttrSetTypeConstraint info) b, a ~ (AttrGetType info)) => AttrLabelProxy (attr :: Symbol) -> (a -> b) -> AttrOp obj tag
- Data.GI.Base.Attributes: class AttrInfo (info :: *) where type AttrAllowedOps info :: [AttrOpTag] type AttrSetTypeConstraint info :: * -> Constraint type AttrBaseTypeConstraint info :: * -> Constraint type AttrGetType info type AttrLabel info :: Symbol where {
+ Data.GI.Base.Attributes: class AttrInfo (info :: *) where type AttrAllowedOps info :: [AttrOpTag] type AttrSetTypeConstraint info :: * -> Constraint type AttrBaseTypeConstraint info :: * -> Constraint type AttrGetType info type AttrLabel info :: Symbol type AttrOrigin info where {
- Data.GI.Base.Attributes: type AttrClearC info obj attr = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, (AttrBaseTypeConstraint info) obj, AttrOpAllowed AttrClear info)
+ Data.GI.Base.Attributes: type AttrClearC info obj attr = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, (AttrBaseTypeConstraint info) obj, AttrOpAllowed AttrClear info obj)
- Data.GI.Base.Attributes: type AttrConstructC info obj attr value = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed AttrConstruct info, (AttrSetTypeConstraint info) value)
+ Data.GI.Base.Attributes: type AttrConstructC info obj attr value = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed AttrConstruct info obj, (AttrSetTypeConstraint info) value)
- Data.GI.Base.Attributes: type AttrGetC info obj attr result = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, (AttrBaseTypeConstraint info) obj, AttrOpAllowed AttrGet info, result ~ AttrGetType info)
+ Data.GI.Base.Attributes: type AttrGetC info obj attr result = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, (AttrBaseTypeConstraint info) obj, AttrOpAllowed AttrGet info obj, result ~ AttrGetType info)
- Data.GI.Base.Attributes: type AttrSetC info obj attr value = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed AttrSet info, (AttrSetTypeConstraint info) value)
+ Data.GI.Base.Attributes: type AttrSetC info obj attr value = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed AttrSet info obj, (AttrSetTypeConstraint info) value)
- Data.GI.Base.Attributes: type family AttrLabel info :: Symbol;
+ Data.GI.Base.Attributes: type family AttrOrigin info;
- Data.GI.Base.BasicTypes: GParamSpec :: (ForeignPtr GParamSpec) -> GParamSpec
+ Data.GI.Base.BasicTypes: GParamSpec :: (ManagedPtr GParamSpec) -> GParamSpec
- Data.GI.Base.BasicTypes: GVariant :: (ForeignPtr GVariant) -> GVariant
+ Data.GI.Base.BasicTypes: GVariant :: (ManagedPtr GVariant) -> GVariant
- Data.GI.Base.BasicTypes: class ForeignPtrNewtype a => BoxedObject a
+ Data.GI.Base.BasicTypes: class ManagedPtrNewtype a => BoxedObject a
- Data.GI.Base.BasicTypes: class ForeignPtrNewtype a => GObject a
+ Data.GI.Base.BasicTypes: class ManagedPtrNewtype a => GObject a
- Data.GI.Base.BasicTypes: class ForeignPtrNewtype a => WrappedPtr a
+ Data.GI.Base.BasicTypes: class ManagedPtrNewtype a => WrappedPtr a
- Data.GI.Base.Closure: Closure :: (ForeignPtr Closure) -> Closure
+ Data.GI.Base.Closure: Closure :: (ManagedPtr Closure) -> Closure
- Data.GI.Base.Constructible: new :: (Constructible a tag, MonadIO m) => (ForeignPtr a -> a) -> [AttrOp a tag] -> m a
+ Data.GI.Base.Constructible: new :: (Constructible a tag, MonadIO m) => (ManagedPtr a -> a) -> [AttrOp a tag] -> m a
- Data.GI.Base.GError: GError :: (ForeignPtr GError) -> GError
+ Data.GI.Base.GError: GError :: (ManagedPtr GError) -> GError
- Data.GI.Base.GObject: constructGObject :: forall o m. (GObject o, MonadIO m) => (ForeignPtr o -> o) -> [AttrOp o AttrConstruct] -> m o
+ Data.GI.Base.GObject: constructGObject :: forall o m. (GObject o, MonadIO m) => (ManagedPtr o -> o) -> [AttrOp o AttrConstruct] -> m o
- Data.GI.Base.GObject: new' :: (MonadIO m, GObject o) => (ForeignPtr o -> o) -> [IO (GValueConstruct o)] -> m o
+ Data.GI.Base.GObject: new' :: (MonadIO m, GObject o) => (ManagedPtr o -> o) -> [IO (GValueConstruct o)] -> m o
- Data.GI.Base.GValue: GValue :: (ForeignPtr GValue) -> GValue
+ Data.GI.Base.GValue: GValue :: (ManagedPtr GValue) -> GValue
- Data.GI.Base.ManagedPtr: castTo :: forall o o'. (GObject o, GObject o') => (ForeignPtr o' -> o') -> o -> IO (Maybe o')
+ Data.GI.Base.ManagedPtr: castTo :: forall o o'. (GObject o, GObject o') => (ManagedPtr o' -> o') -> o -> IO (Maybe o')
- Data.GI.Base.ManagedPtr: maybeWithManagedPtr :: ForeignPtrNewtype a => Maybe a -> (Ptr a -> IO c) -> IO c
+ Data.GI.Base.ManagedPtr: maybeWithManagedPtr :: ManagedPtrNewtype a => Maybe a -> (Ptr a -> IO c) -> IO c
- Data.GI.Base.ManagedPtr: newBoxed :: forall a. BoxedObject a => (ForeignPtr a -> a) -> Ptr a -> IO a
+ Data.GI.Base.ManagedPtr: newBoxed :: forall a. BoxedObject a => (ManagedPtr a -> a) -> Ptr a -> IO a
- Data.GI.Base.ManagedPtr: newManagedPtr :: FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
+ Data.GI.Base.ManagedPtr: newManagedPtr :: Ptr a -> IO () -> IO (ManagedPtr a)
- Data.GI.Base.ManagedPtr: newObject :: (GObject a, GObject b) => (ForeignPtr a -> a) -> Ptr b -> IO a
+ Data.GI.Base.ManagedPtr: newObject :: (GObject a, GObject b) => (ManagedPtr a -> a) -> Ptr b -> IO a
- Data.GI.Base.ManagedPtr: newPtr :: WrappedPtr a => (ForeignPtr a -> a) -> Ptr a -> IO a
+ Data.GI.Base.ManagedPtr: newPtr :: WrappedPtr a => (ManagedPtr a -> a) -> Ptr a -> IO a
- Data.GI.Base.ManagedPtr: touchManagedPtr :: forall a. ForeignPtrNewtype a => a -> IO ()
+ Data.GI.Base.ManagedPtr: touchManagedPtr :: forall a. ManagedPtrNewtype a => a -> IO ()
- Data.GI.Base.ManagedPtr: unsafeCastTo :: forall o o'. (HasCallStack, GObject o, GObject o') => (ForeignPtr o' -> o') -> o -> IO o'
+ Data.GI.Base.ManagedPtr: unsafeCastTo :: forall o o'. (HasCallStack, GObject o, GObject o') => (ManagedPtr o' -> o') -> o -> IO o'
- Data.GI.Base.ManagedPtr: unsafeManagedPtrCastPtr :: forall a b. ForeignPtrNewtype a => a -> Ptr b
+ Data.GI.Base.ManagedPtr: unsafeManagedPtrCastPtr :: forall a b. (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr b)
- Data.GI.Base.ManagedPtr: unsafeManagedPtrGetPtr :: ForeignPtrNewtype a => a -> Ptr a
+ Data.GI.Base.ManagedPtr: unsafeManagedPtrGetPtr :: (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)
- Data.GI.Base.ManagedPtr: withManagedPtr :: ForeignPtrNewtype a => a -> (Ptr a -> IO c) -> IO c
+ Data.GI.Base.ManagedPtr: withManagedPtr :: ManagedPtrNewtype a => a -> (Ptr a -> IO c) -> IO c
- Data.GI.Base.ManagedPtr: withManagedPtrList :: ForeignPtrNewtype a => [a] -> ([Ptr a] -> IO c) -> IO c
+ Data.GI.Base.ManagedPtr: withManagedPtrList :: ManagedPtrNewtype a => [a] -> ([Ptr a] -> IO c) -> IO c
- Data.GI.Base.ManagedPtr: wrapBoxed :: forall a. BoxedObject a => (ForeignPtr a -> a) -> Ptr a -> IO a
+ Data.GI.Base.ManagedPtr: wrapBoxed :: forall a. BoxedObject a => (ManagedPtr a -> a) -> Ptr a -> IO a
- Data.GI.Base.ManagedPtr: wrapObject :: forall a b. (GObject a, GObject b) => (ForeignPtr a -> a) -> Ptr b -> IO a
+ Data.GI.Base.ManagedPtr: wrapObject :: forall a b. (GObject a, GObject b) => (ManagedPtr a -> a) -> Ptr b -> IO a
- Data.GI.Base.ManagedPtr: wrapPtr :: WrappedPtr a => (ForeignPtr a -> a) -> Ptr a -> IO a
+ Data.GI.Base.ManagedPtr: wrapPtr :: WrappedPtr a => (ManagedPtr a -> a) -> Ptr a -> IO a
- Data.GI.Base.Properties: getObjectPropertyBoxed :: forall a b. (GObject a, BoxedObject b) => a -> String -> (ForeignPtr b -> b) -> IO (Maybe b)
+ Data.GI.Base.Properties: getObjectPropertyBoxed :: forall a b. (GObject a, BoxedObject b) => a -> String -> (ManagedPtr b -> b) -> IO (Maybe b)
- Data.GI.Base.Properties: getObjectPropertyObject :: forall a b. (GObject a, GObject b) => a -> String -> (ForeignPtr b -> b) -> IO (Maybe b)
+ Data.GI.Base.Properties: getObjectPropertyObject :: forall a b. (GObject a, GObject b) => a -> String -> (ManagedPtr b -> b) -> IO (Maybe b)

Files

+ Data/GI/Base.hs view
@@ -0,0 +1,33 @@+{- |+   == Convenience header for basic GObject-Introspection modules++See the documentation for each individual module for a description and+usage help.+-}+module Data.GI.Base+    ( module Data.GI.Base.Attributes+    , module Data.GI.Base.BasicConversions+    , module Data.GI.Base.BasicTypes+    , module Data.GI.Base.Closure+    , module Data.GI.Base.Constructible+    , module Data.GI.Base.GError+    , module Data.GI.Base.GHashTable+    , module Data.GI.Base.GObject+    , module Data.GI.Base.GValue+    , module Data.GI.Base.GVariant+    , module Data.GI.Base.ManagedPtr+    , module Data.GI.Base.Signals+    ) where++import Data.GI.Base.Attributes (get, set, AttrOp(..))+import Data.GI.Base.BasicConversions+import Data.GI.Base.BasicTypes+import Data.GI.Base.Closure+import Data.GI.Base.Constructible (new)+import Data.GI.Base.GError+import Data.GI.Base.GHashTable+import Data.GI.Base.GObject (new')+import Data.GI.Base.GValue (GValue(..), IsGValue(..))+import Data.GI.Base.GVariant+import Data.GI.Base.ManagedPtr+import Data.GI.Base.Signals (on, after, SignalProxy(PropertyNotify))
+ Data/GI/Base/Attributes.hs view
@@ -0,0 +1,378 @@+{-# LANGUAGE GADTs, ScopedTypeVariables, DataKinds, KindSignatures,+  TypeFamilies, TypeOperators, MultiParamTypeClasses, ConstraintKinds,+  UndecidableInstances, FlexibleInstances #-}++-- |+--+-- == Basic attributes interface+--+-- Attributes of an object can be get, set and constructed. For types+-- descending from 'Data.GI.Base.BasicTypes.GObject', properties are+-- encoded in attributes, although attributes are slightly more+-- general (every property of a `Data.GI.Base.BasicTypes.GObject` is an+-- attribute, but we can also have attributes for types not descending+-- from `Data.GI.Base.BasicTypes.GObject`).+--+-- As an example consider a @button@ widget and a property (of the+-- Button class, or any of its parent classes or implemented+-- interfaces) called "label". The simplest way of getting the value+-- of the button is to do+--+-- > value <- getButtonLabel button+--+-- And for setting:+--+-- > setButtonLabel button label+--+-- This mechanism quickly becomes rather cumbersome, for example for+-- setting the "window" property in a DOMDOMWindow in WebKit:+--+-- > win <- getDOMDOMWindowWindow dom+--+-- and perhaps more importantly, one needs to chase down the type+-- which introduces the property:+--+-- > setWidgetSensitive button False+--+-- There is no @setButtonSensitive@, since it is the @Widget@ type+-- that introduces the "sensitive" property.+--+-- == Overloaded attributes+--+-- A much more convenient overloaded attribute resolution API is+-- provided by this module. Getting the value of an object's attribute+-- is straightforward:+--+-- > value <- get button _label+--+-- The definition of @_label@ is basically a 'Proxy' encoding the name+-- of the attribute to get:+--+-- > _label = fromLabelProxy (Proxy :: Proxy "label")+--+-- These proxies can be automatically generated by invoking the code+-- generator with the @-l@ option. The leading underscore is simply so+-- the autogenerated identifiers do not pollute the namespace, but if+-- this is not a concern the autogenerated names (in the autogenerated+-- @GI/Properties.hs@) can be edited as one wishes.+--+-- In addition, for ghc >= 8.0, one can directly use the overloaded+-- labels provided by GHC itself. Using the "OverloadedLabels"+-- extension, the code above can also be written as+--+-- > value <- get button #label+--+-- The syntax for setting or updating an attribute is only slightly more+-- complex. At the simplest level it is just:+--+-- > set button [ _label := value ]+--+-- or for the WebKit example above+--+-- > set dom [_window := win]+--+-- However as the list notation would indicate, you can set or update multiple+-- attributes of the same object in one go:+--+-- > set button [ _label := value, _sensitive := False ]+--+-- You are not limited to setting the value of an attribute, you can also+-- apply an update function to an attribute's value. That is the function+-- receives the current value of the attribute and returns the new value.+--+-- > set spinButton [ _value :~ (+1) ]+--+-- There are other variants of these operators, see 'AttrOp'+-- below. ':=>' and ':~>' are like ':=' and ':~' but operate in the+-- 'IO' monad rather than being pure. There is also '::=' and '::~'+-- which take the object as an extra parameter.+--+-- Attributes can also be set during construction of a+-- `Data.GI.Base.BasicTypes.GObject` using `Data.GI.Base.Properties.new`+--+-- > button <- new Button [_label := "Can't touch this!", _sensitive := False]+--+-- In addition for value being set/get having to have the right type,+-- there can be attributes that are read-only, or that can only be set+-- during construction with `Data.GI.Base.Properties.new`, but cannot be+-- `set` afterwards. That these invariants hold is also checked during+-- compile time.+--+-- == Nullable atributes+--+-- Whenever the attribute is represented as a pointer in the C side,+-- it is often the case that the underlying C representation admits or+-- returns @NULL@ as a valid value for the property. In these cases+-- the `get` operation may return a `Maybe` value, with `Nothing`+-- representing the @NULL@ pointer value (notable exceptions are+-- `Data.GI.Base.BasicTypes.GList` and+-- `Data.GI.Base.BasicTypes.GSList`, for which @NULL@ is represented+-- simply as he empty list). This can be overriden in the+-- introspection data, since sometimes attributes are non-nullable,+-- even if the type would allow for @NULL@.+--+-- For convenience, in nullable cases the `set` operation will by+-- default /not/ take a `Maybe` value, but rather assume that the+-- caller wants to set a non-@NULL@ value. If setting a @NULL@ value+-- is desired, use `clear` as follows+--+-- > clear object _propName+--+module Data.GI.Base.Attributes (+  AttrInfo(..),++  AttrOpTag(..),++  AttrOp(..),+  AttrOpAllowed,++  AttrGetC,+  AttrSetC,+  AttrConstructC,+  AttrClearC,++  get,+  set,+  clear,++  AttrLabelProxy(..)+  ) where++import Control.Monad.IO.Class (MonadIO, liftIO)++import Data.Proxy (Proxy(..))++import Data.GI.Base.GValue (GValueConstruct)+import Data.GI.Base.Overloading (HasAttributeList,+                                 ResolveAttribute, IsLabelProxy(..))++import GHC.TypeLits+import GHC.Exts (Constraint)++#if MIN_VERSION_base(4,9,0)+import GHC.OverloadedLabels (IsLabel(..))+#endif++infixr 0 :=,:~,:=>,:~>,::=,::~++-- | A proxy for attribute labels.+data AttrLabelProxy (a :: Symbol) = AttrLabelProxy++-- | Support for overloaded labels.+instance a ~ x => IsLabelProxy x (AttrLabelProxy a) where+    fromLabelProxy _ = AttrLabelProxy++#if MIN_VERSION_base(4,9,0)+instance a ~ x => IsLabel x (AttrLabelProxy a) where+    fromLabel _ = AttrLabelProxy+#endif++-- | Info describing an attribute.+class AttrInfo (info :: *) where+    -- | The operations that are allowed on the attribute.+    type AttrAllowedOps info :: [AttrOpTag]+    -- | Constraint on the value being set.+    type AttrSetTypeConstraint info :: * -> Constraint+    -- | Constraint on the type for which we are allowed to+    -- create\/set\/get the attribute.+    type AttrBaseTypeConstraint info :: * -> Constraint+    -- | Type returned by `attrGet`.+    type AttrGetType info+    -- | Name of the attribute.+    type AttrLabel info :: Symbol+    -- | Type which introduces the attribute.+    type AttrOrigin info+    -- | Get the value of the given attribute.+    attrGet :: AttrBaseTypeConstraint info o =>+               Proxy info -> o -> IO (AttrGetType info)+    -- | Set the value of the given attribute, after the object having+    -- the attribute has already been created.+    attrSet :: (AttrBaseTypeConstraint info o,+                AttrSetTypeConstraint info b) =>+               Proxy info -> o -> b -> IO ()+    -- | Set the value of the given attribute to @NULL@ (for nullable+    -- attributes).+    attrClear :: AttrBaseTypeConstraint info o =>+                 Proxy info -> o -> IO ()+    -- | Build a `GValue` representing the attribute.+    attrConstruct :: (AttrBaseTypeConstraint info o,+                      AttrSetTypeConstraint info b) =>+                     Proxy info -> b -> IO (GValueConstruct o)++-- | Result of checking whether an op is allowed on an attribute.+data OpAllowed tag attrName definingType useType =+    OpIsAllowed+#if !MIN_VERSION_base(4,9,0)+        | AttrOpNotAllowed Symbol tag Symbol definingType Symbol attrName+#endif++#if MIN_VERSION_base(4,9,0)+type family TypeOriginInfo definingType useType :: ErrorMessage where+    TypeOriginInfo definingType definingType =+        'Text "‘" ':<>: 'ShowType definingType ':<>: 'Text "’"+    TypeOriginInfo definingType useType =+        'Text "‘" ':<>: 'ShowType useType ':<>:+        'Text "’ (inherited from parent type ‘" ':<>:+        'ShowType definingType ':<>: 'Text "’)"+#endif++-- | Look in the given list to see if the given `AttrOp` is a member,+-- if not return an error type.+type family AttrOpIsAllowed (tag :: AttrOpTag) (ops :: [AttrOpTag]) (label :: Symbol) (definingType :: *) (useType :: *) :: OpAllowed AttrOpTag Symbol * * where+    AttrOpIsAllowed tag '[] label definingType useType =+#if !MIN_VERSION_base(4,9,0)+        'AttrOpNotAllowed "Error: operation " tag " not allowed for attribute " definingType "." label+#else+        TypeError ('Text "Attribute ‘" ':<>: 'Text label ':<>:+                   'Text "’ for type " ':<>:+                   TypeOriginInfo definingType useType ':<>:+                   'Text " is not " ':<>:+                   'Text (AttrOpText tag) ':<>: 'Text ".")+#endif+    AttrOpIsAllowed tag (tag ': ops) label definingType useType = 'OpIsAllowed+    AttrOpIsAllowed tag (other ': ops) label definingType useType = AttrOpIsAllowed tag ops label definingType useType++-- | Whether a given `AttrOpTag` is allowed on an attribute, given the+-- info type.+type family AttrOpAllowed (tag :: AttrOpTag) (info :: *) (useType :: *) :: Constraint where+    AttrOpAllowed tag info useType =+        AttrOpIsAllowed tag (AttrAllowedOps info) (AttrLabel info) (AttrOrigin info) useType ~ 'OpIsAllowed++-- | Possible operations on an attribute.+data AttrOpTag = AttrGet | AttrSet | AttrConstruct | AttrClear++#if MIN_VERSION_base(4,9,0)+-- | A user friendly description of the `AttrOpTag`, useful when+-- printing type errors.+type family AttrOpText (tag :: AttrOpTag) :: Symbol where+    AttrOpText 'AttrGet = "gettable"+    AttrOpText 'AttrSet = "settable"+    AttrOpText 'AttrConstruct = "constructible"+    AttrOpText 'AttrClear = "nullable"+#endif++-- | Constraint on a @obj@\/@attr@ pair so that `set` works on values+-- of type @value@.+type AttrSetC info obj attr value = (HasAttributeList obj,+                                     info ~ ResolveAttribute attr obj,+                                     AttrInfo info,+                                     AttrBaseTypeConstraint info obj,+                                     AttrOpAllowed 'AttrSet info obj,+                                     (AttrSetTypeConstraint info) value)++-- | Constraint on a @obj@\/@value@ pair so that `new` works on values+-- of type @@value@.+type AttrConstructC info obj attr value = (HasAttributeList obj,+                                           info ~ ResolveAttribute attr obj,+                                           AttrInfo info,+                                           AttrBaseTypeConstraint info obj,+                                           AttrOpAllowed 'AttrConstruct info obj,+                                           (AttrSetTypeConstraint info) value)++-- | Constructors for the different operations allowed on an attribute.+data AttrOp obj (tag :: AttrOpTag) where+    -- Assign a value to an attribute+    (:=)  :: (HasAttributeList obj,+              info ~ ResolveAttribute attr obj,+              AttrInfo info,+              AttrBaseTypeConstraint info obj,+              AttrOpAllowed tag info obj,+              (AttrSetTypeConstraint info) b) =>+             AttrLabelProxy (attr :: Symbol) -> b -> AttrOp obj tag+    -- Assign the result of an IO action to an attribute+    (:=>) :: (HasAttributeList obj,+              info ~ ResolveAttribute attr obj,+              AttrInfo info,+              AttrBaseTypeConstraint info obj,+              AttrOpAllowed tag info obj,+              (AttrSetTypeConstraint info) b) =>+             AttrLabelProxy (attr :: Symbol) -> IO b -> AttrOp obj tag+    -- Apply an update function to an attribute+    (:~)  :: (HasAttributeList obj,+              info ~ ResolveAttribute attr obj,+              AttrInfo info,+              AttrBaseTypeConstraint info obj,+              tag ~ 'AttrSet,+              AttrOpAllowed 'AttrSet info obj,+              AttrOpAllowed 'AttrGet info obj,+              (AttrSetTypeConstraint info) b,+              a ~ (AttrGetType info)) =>+             AttrLabelProxy (attr :: Symbol) -> (a -> b) -> AttrOp obj tag+    -- Apply an IO update function to an attribute+    (:~>) :: (HasAttributeList obj,+              info ~ ResolveAttribute attr obj,+              AttrInfo info,+              AttrBaseTypeConstraint info obj,+              tag ~ 'AttrSet,+              AttrOpAllowed 'AttrSet info obj,+              AttrOpAllowed 'AttrGet info obj,+              (AttrSetTypeConstraint info) b,+              a ~ (AttrGetType info)) =>+             AttrLabelProxy (attr :: Symbol) -> (a -> IO b) -> AttrOp obj tag+    -- Assign a value to an attribute with the object as an argument+    (::=) :: (HasAttributeList obj,+              info ~ ResolveAttribute attr obj,+              AttrInfo info,+              AttrBaseTypeConstraint info obj,+              tag ~ 'AttrSet,+              AttrOpAllowed tag info obj,+              (AttrSetTypeConstraint info) b) =>+             AttrLabelProxy (attr :: Symbol) -> (obj -> b) -> AttrOp obj tag+    -- Apply an update function to an attribute with the object as an+    -- argument+    (::~) :: (HasAttributeList obj,+              info ~ ResolveAttribute attr obj,+              AttrInfo info,+              AttrBaseTypeConstraint info obj,+              tag ~ 'AttrSet,+              AttrOpAllowed 'AttrSet info obj,+              AttrOpAllowed 'AttrGet info obj,+              (AttrSetTypeConstraint info) b,+              a ~ (AttrGetType info)) =>+             AttrLabelProxy (attr :: Symbol) -> (obj -> a -> b) -> AttrOp obj tag++-- | Set a number of properties for some object.+set :: forall o m. MonadIO m => o -> [AttrOp o 'AttrSet] -> m ()+set obj = liftIO . mapM_ app+ where+   resolve :: AttrLabelProxy attr -> Proxy (ResolveAttribute attr o)+   resolve _ = Proxy++   app :: AttrOp o 'AttrSet -> IO ()+   app (attr :=  x) = attrSet (resolve attr) obj x+   app (attr :=> x) = x >>= attrSet (resolve attr) obj+   app (attr :~  f) = attrGet (resolve attr) obj >>=+                      \v -> attrSet (resolve attr) obj (f v)+   app (attr :~> f) = attrGet (resolve attr) obj >>= f >>=+                      attrSet (resolve attr) obj+   app (attr ::= f) = attrSet (resolve attr) obj (f obj)+   app (attr ::~ f) = attrGet (resolve attr) obj >>=+                      \v -> attrSet (resolve attr) obj (f obj v)++-- | Constraints on a @obj@\/@attr@ pair so `get` is possible,+-- producing a value of type @result@.+type AttrGetC info obj attr result = (HasAttributeList obj,+                                      info ~ ResolveAttribute attr obj,+                                      AttrInfo info,+                                      (AttrBaseTypeConstraint info) obj,+                                      AttrOpAllowed 'AttrGet info obj,+                                      result ~ AttrGetType info)++-- | Get the value of an attribute for an object.+get :: forall info attr obj result m.+       (AttrGetC info obj attr result, MonadIO m) =>+        obj -> AttrLabelProxy (attr :: Symbol) -> m result+get o _ = liftIO $ attrGet (Proxy :: Proxy info) o++-- | Constraint on a @obj@\/@attr@ pair so that `clear` is allowed.+type AttrClearC info obj attr = (HasAttributeList obj,+                                 info ~ ResolveAttribute attr obj,+                                 AttrInfo info,+                                 (AttrBaseTypeConstraint info) obj,+                                 AttrOpAllowed 'AttrClear info obj)++-- | Set a nullable attribute to @NULL@.+clear :: forall info attr obj m.+         (AttrClearC info obj attr, MonadIO m) =>+         obj -> AttrLabelProxy (attr :: Symbol) -> m ()+clear o _ = liftIO $ attrClear (Proxy :: Proxy info) o
+ Data/GI/Base/BasicConversions.hsc view
@@ -0,0 +1,595 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# OPTIONS_GHC -fno-warn-name-shadowing #-}+module Data.GI.Base.BasicConversions+    ( gflagsToWord+    , wordToGFlags++    , packGList+    , unpackGList+    , packGSList+    , unpackGSList+    , packGArray+    , unpackGArray+    , unrefGArray+    , packGPtrArray+    , unpackGPtrArray+    , unrefPtrArray+    , packGByteArray+    , unpackGByteArray+    , unrefGByteArray+    , packGHashTable+    , unpackGHashTable+    , unrefGHashTable+    , packByteString+    , packZeroTerminatedByteString+    , unpackByteStringWithLength+    , unpackZeroTerminatedByteString+    , packFileNameArray+    , packZeroTerminatedFileNameArray+    , unpackZeroTerminatedFileNameArray+    , unpackFileNameArrayWithLength+    , packUTF8CArray+    , packZeroTerminatedUTF8CArray+    , unpackUTF8CArrayWithLength+    , unpackZeroTerminatedUTF8CArray+    , packStorableArray+    , packZeroTerminatedStorableArray+    , unpackStorableArrayWithLength+    , unpackZeroTerminatedStorableArray+    , packMapStorableArray+    , packMapZeroTerminatedStorableArray+    , unpackMapStorableArrayWithLength+    , unpackMapZeroTerminatedStorableArray+    , packPtrArray+    , packZeroTerminatedPtrArray+    , unpackPtrArrayWithLength+    , unpackZeroTerminatedPtrArray+    , packBlockArray+    , unpackBlockArrayWithLength+    , unpackBoxedArrayWithLength++    , stringToCString+    , cstringToString+    , textToCString+    , withTextCString+    , cstringToText+    , byteStringToCString+    , cstringToByteString++    , mapZeroTerminatedCArray+    , mapCArrayWithLength+    , mapGArray+    , mapPtrArray+    , mapGList+    , mapGSList+    ) where++#if !MIN_VERSION_base(4,8,0)+import Control.Applicative ((<$>), (<*>))+#endif+import Control.Exception.Base (bracket)+import Control.Monad (foldM)++import Data.ByteString (ByteString)+import qualified Data.ByteString as B+import qualified Data.ByteString.Internal as BI+import Data.Maybe (fromMaybe)+import Data.Text (Text)+import qualified Data.Text.Foreign as TF++import Foreign.Ptr (Ptr, plusPtr, nullPtr, nullFunPtr, castPtr)+import Foreign.ForeignPtr (withForeignPtr)+import Foreign.Storable (Storable, peek, poke, sizeOf)+import Foreign.C.Types (CInt(..), CUInt(..), CSize(..), CChar(..))+import Foreign.C.String (CString, withCString, peekCString)+import Data.Word+import Data.Int (Int32)+import Data.Bits (Bits, (.|.), (.&.), shift)++import Data.GI.Base.BasicTypes+import Data.GI.Base.GHashTable (GEqualFunc, GHashFunc)+import Data.GI.Base.ManagedPtr (copyBoxedPtr)+import Data.GI.Base.Utils (allocBytes, callocBytes, memcpy, freeMem)++#include <glib-object.h>++gflagsToWord :: (Num b, IsGFlag a) => [a] -> b+gflagsToWord flags = fromIntegral (go flags)+    where go (f:fs) = fromEnum f .|. go fs+          go [] = 0++wordToGFlags :: (Storable a, Integral a, Bits a, IsGFlag b) => a -> [b]+wordToGFlags w = go 0+    where+      nbits = (sizeOf w)*8+      go k+          | k == nbits = []+          | otherwise = if mask .&. w /= 0+                        then toEnum (fromIntegral mask) : go (k+1)+                        else go (k+1)+          where mask = shift 1 k++foreign import ccall "g_list_prepend" g_list_prepend ::+    Ptr (GList (Ptr a)) -> Ptr a -> IO (Ptr (GList (Ptr a)))++-- Given a Haskell list of items, construct a GList with those values.+packGList   :: [Ptr a] -> IO (Ptr (GList (Ptr a)))+packGList l = foldM g_list_prepend nullPtr $ reverse l++-- Given a GSList construct the corresponding Haskell list.+unpackGList   :: Ptr (GList (Ptr a)) -> IO [Ptr a]+unpackGList gsl+    | gsl == nullPtr = return []+    | otherwise =+        do x <- peek (castPtr gsl)+           next <- peek (gsl `plusPtr` sizeOf x)+           xs <- unpackGList next+           return $ x : xs++-- Same thing for singly linked lists++foreign import ccall "g_slist_prepend" g_slist_prepend ::+    Ptr (GSList (Ptr a)) -> Ptr a -> IO (Ptr (GSList (Ptr a)))++-- Given a Haskell list of items, construct a GSList with those values.+packGSList   :: [Ptr a] -> IO (Ptr (GSList (Ptr a)))+packGSList l = foldM g_slist_prepend nullPtr $ reverse l++-- Given a GSList construct the corresponding Haskell list.+unpackGSList   :: Ptr (GSList (Ptr a)) -> IO [Ptr a]+unpackGSList gsl = unpackGList (castPtr gsl)++foreign import ccall "g_array_new" g_array_new ::+   CInt -> CInt -> CUInt -> IO (Ptr (GArray ()))+foreign import ccall "g_array_set_size" g_array_set_size ::+    Ptr (GArray ()) -> CUInt -> IO (Ptr (GArray ()))+foreign import ccall "g_array_unref" unrefGArray ::+   Ptr (GArray a) -> IO ()++packGArray :: forall a. Storable a => [a] -> IO (Ptr (GArray a))+packGArray elems = do+  let elemsize = sizeOf (elems!!0)+  array <- g_array_new 0 0 (fromIntegral elemsize)+  _ <- g_array_set_size array (fromIntegral $ length elems)+  dataPtr <- peek (castPtr array :: Ptr (Ptr a))+  fill dataPtr elems+  return $ castPtr array+  where+    fill            :: Ptr a -> [a] -> IO ()+    fill _ []       = return ()+    fill ptr (x:xs) =+        do poke ptr x+           fill (ptr `plusPtr` (sizeOf x)) xs++unpackGArray :: forall a. Storable a => Ptr (GArray a) -> IO [a]+unpackGArray array = do+  dataPtr <- peek (castPtr array :: Ptr (Ptr a))+  nitems <- peek (array `plusPtr` sizeOf dataPtr)+  go dataPtr nitems+    where go :: Ptr a -> Int -> IO [a]+          go _ 0 = return []+          go ptr n = do+            x <- peek ptr+            (x:) <$> go (ptr `plusPtr` sizeOf x) (n-1)++foreign import ccall "g_ptr_array_new" g_ptr_array_new ::+    IO (Ptr (GPtrArray ()))+foreign import ccall "g_ptr_array_set_size" g_ptr_array_set_size ::+    Ptr (GPtrArray ()) -> CUInt -> IO (Ptr (GPtrArray ()))+foreign import ccall "g_ptr_array_unref" unrefPtrArray ::+   Ptr (GPtrArray a) -> IO ()++packGPtrArray :: [Ptr a] -> IO (Ptr (GPtrArray (Ptr a)))+packGPtrArray elems = do+  array <- g_ptr_array_new+  _ <- g_ptr_array_set_size array (fromIntegral $ length elems)+  dataPtr <- peek (castPtr array :: Ptr (Ptr (Ptr a)))+  fill dataPtr elems+  return $ castPtr array+  where+    fill            :: Ptr (Ptr a) -> [Ptr a] -> IO ()+    fill _ []       = return ()+    fill ptr (x:xs) =+        do poke ptr x+           fill (ptr `plusPtr` (sizeOf x)) xs++unpackGPtrArray :: Ptr (GPtrArray (Ptr a)) -> IO [Ptr a]+unpackGPtrArray array = do+  dataPtr <- peek (castPtr array :: Ptr (Ptr (Ptr a)))+  nitems <- peek (array `plusPtr` sizeOf dataPtr)+  go dataPtr nitems+    where go :: Ptr (Ptr a) -> Int -> IO [Ptr a]+          go _ 0 = return []+          go ptr n = do+            x <- peek ptr+            (x:) <$> go (ptr `plusPtr` sizeOf x) (n-1)++foreign import ccall "g_byte_array_new" g_byte_array_new ::+    IO (Ptr GByteArray)+foreign import ccall "g_byte_array_append" g_byte_array_append ::+    Ptr GByteArray -> Ptr a -> CUInt -> IO (Ptr GByteArray)+foreign import ccall "g_byte_array_unref" unrefGByteArray ::+   Ptr GByteArray -> IO ()++packGByteArray :: ByteString -> IO (Ptr GByteArray)+packGByteArray bs = do+  array <- g_byte_array_new+  let (ptr, offset, length) = BI.toForeignPtr bs+  _ <- withForeignPtr ptr $ \dataPtr ->+                    g_byte_array_append array (dataPtr `plusPtr` offset)+                                        (fromIntegral length)+  return array++unpackGByteArray :: Ptr GByteArray -> IO ByteString+unpackGByteArray array = do+  dataPtr <- peek (castPtr array :: Ptr (Ptr CChar))+  length <- peek (array `plusPtr` (sizeOf dataPtr)) :: IO CUInt+  B.packCStringLen (dataPtr, fromIntegral length)++foreign import ccall "g_hash_table_new_full" g_hash_table_new_full ::+    GHashFunc a -> GEqualFunc a -> GDestroyNotify a -> GDestroyNotify b ->+                 IO (Ptr (GHashTable a b))+foreign import ccall "g_hash_table_insert" g_hash_table_insert ::+    Ptr (GHashTable a b) -> PtrWrapped a -> PtrWrapped b -> IO #{type gboolean}++packGHashTable :: GHashFunc a -> GEqualFunc a ->+                  Maybe (GDestroyNotify a) -> Maybe (GDestroyNotify b) ->+                  [(PtrWrapped a, PtrWrapped b)] -> IO (Ptr (GHashTable a b))+packGHashTable keyHash keyEqual keyDestroy elemDestroy pairs = do+  let keyDPtr = fromMaybe nullFunPtr keyDestroy+      elemDPtr = fromMaybe nullFunPtr elemDestroy+  ht <- g_hash_table_new_full keyHash keyEqual keyDPtr elemDPtr+  mapM_ (uncurry (g_hash_table_insert ht)) pairs+  return ht++foreign import ccall "g_hash_table_get_keys" g_hash_table_get_keys ::+    Ptr (GHashTable a b) -> IO (Ptr (GList (Ptr a)))+foreign import ccall "g_hash_table_lookup" g_hash_table_lookup ::+    Ptr (GHashTable a b) -> PtrWrapped a -> IO (PtrWrapped b)+unpackGHashTable :: Ptr (GHashTable a b) -> IO [(PtrWrapped a, PtrWrapped b)]+unpackGHashTable ht = do+  keysGList <- g_hash_table_get_keys ht+  keys <- (map (PtrWrapped . castPtr)) <$> unpackGList keysGList+  g_list_free keysGList+  -- At this point we could use g_hash_table_get_values, since the+  -- current implementation in GLib returns elements in the same order+  -- as g_hash_table_get_keys. But to be on the safe side, since the+  -- ordering is not specified in the documentation, we do the+  -- following, which is (quite) slower but manifestly safe.+  elems <- mapM (g_hash_table_lookup ht) keys+  return (zip keys elems)++foreign import ccall "g_hash_table_unref" unrefGHashTable ::+   Ptr (GHashTable a b) -> IO ()++packByteString :: ByteString -> IO (Ptr Word8)+packByteString bs = do+  let (ptr, offset, length) = BI.toForeignPtr bs+  mem <- allocBytes length+  withForeignPtr ptr $ \dataPtr ->+      memcpy mem (dataPtr `plusPtr` offset) (fromIntegral length)+  return mem++packZeroTerminatedByteString :: ByteString -> IO (Ptr Word8)+packZeroTerminatedByteString bs = do+  let (ptr, offset, length) = BI.toForeignPtr bs+  mem <- allocBytes (length+1)+  withForeignPtr ptr $ \dataPtr ->+      memcpy mem (dataPtr `plusPtr` offset) (fromIntegral length)+  poke (mem `plusPtr` (offset+length)) (0 :: Word8)+  return mem++unpackByteStringWithLength :: Integral a => a -> Ptr Word8 -> IO ByteString+unpackByteStringWithLength length ptr =+  B.packCStringLen (castPtr ptr, fromIntegral length)++unpackZeroTerminatedByteString :: Ptr Word8 -> IO ByteString+unpackZeroTerminatedByteString ptr =+  B.packCString (castPtr ptr)++packStorableArray :: Storable a => [a] -> IO (Ptr a)+packStorableArray = packMapStorableArray id++packZeroTerminatedStorableArray :: (Num a, Storable a) => [a] -> IO (Ptr a)+packZeroTerminatedStorableArray = packMapZeroTerminatedStorableArray id++unpackStorableArrayWithLength :: (Integral a, Storable b) =>+                                 a -> Ptr b -> IO [b]+unpackStorableArrayWithLength = unpackMapStorableArrayWithLength id++unpackZeroTerminatedStorableArray :: (Eq a, Num a, Storable a) =>+                                     Ptr a -> IO [a]+unpackZeroTerminatedStorableArray = unpackMapZeroTerminatedStorableArray id++packMapStorableArray :: forall a b. Storable b => (a -> b) -> [a] -> IO (Ptr b)+packMapStorableArray fn items = do+  let nitems = length items+  mem <- allocBytes $ (sizeOf (undefined::b)) * nitems+  fill mem (map fn items)+  return mem+  where fill            :: Ptr b -> [b] -> IO ()+        fill _ []       = return ()+        fill ptr (x:xs) = do+          poke ptr x+          fill (ptr `plusPtr` sizeOf x) xs++packMapZeroTerminatedStorableArray :: forall a b. (Num b, Storable b) =>+                                      (a -> b) -> [a] -> IO (Ptr b)+packMapZeroTerminatedStorableArray fn items = do+  let nitems = length items+  mem <- allocBytes $ (sizeOf (undefined::b)) * (nitems+1)+  fill mem (map fn items)+  return mem+  where fill            :: Ptr b -> [b] -> IO ()+        fill ptr []     = poke ptr 0+        fill ptr (x:xs) = do+          poke ptr x+          fill (ptr `plusPtr` sizeOf x) xs++unpackMapStorableArrayWithLength :: forall a b c. (Integral a, Storable b) =>+                                    (b -> c) -> a -> Ptr b -> IO [c]+unpackMapStorableArrayWithLength fn n ptr = map fn <$> go (fromIntegral n) ptr+    where go :: Int -> Ptr b -> IO [b]+          go 0 _ = return []+          go n ptr = do+            x <- peek ptr+            (x:) <$> go (n-1) (ptr `plusPtr` sizeOf x)++unpackMapZeroTerminatedStorableArray :: forall a b. (Eq a, Num a, Storable a) =>+                                        (a -> b) -> Ptr a -> IO [b]+unpackMapZeroTerminatedStorableArray fn ptr = map fn <$> go ptr+    where go :: Ptr a -> IO [a]+          go ptr = do+            x <- peek ptr+            if x == 0+            then return []+            else (x:) <$> go (ptr `plusPtr` sizeOf x)++packUTF8CArray :: [Text] -> IO (Ptr CString)+packUTF8CArray items = do+  let nitems = length items+  mem <- allocBytes $ nitems * (sizeOf (nullPtr :: CString))+  fill mem items+  return mem+    where fill            :: Ptr CString -> [Text] -> IO ()+          fill _ []       = return ()+          fill ptr (x:xs) =+              do cstring <- textToCString x+                 poke ptr cstring+                 fill (ptr `plusPtr` sizeOf cstring) xs++packZeroTerminatedUTF8CArray :: [Text] -> IO (Ptr CString)+packZeroTerminatedUTF8CArray items = do+    let nitems = length items+    mem <- allocBytes $ (sizeOf (nullPtr :: CString)) * (nitems+1)+    fill mem items+    return mem+    where fill :: Ptr CString -> [Text] -> IO ()+          fill ptr [] = poke ptr nullPtr+          fill ptr (x:xs) = do cstring <- textToCString x+                               poke ptr cstring+                               fill (ptr `plusPtr` sizeOf cstring) xs++unpackZeroTerminatedUTF8CArray :: Ptr CString -> IO [Text]+unpackZeroTerminatedUTF8CArray listPtr = go listPtr+    where go :: Ptr CString -> IO [Text]+          go ptr = do+            cstring <- peek ptr+            if cstring == nullPtr+               then return []+               else (:) <$> cstringToText cstring+                        <*> go (ptr `plusPtr` sizeOf cstring)++unpackUTF8CArrayWithLength :: Integral a => a -> Ptr CString -> IO [Text]+unpackUTF8CArrayWithLength n ptr = go (fromIntegral n) ptr+    where go       :: Int -> Ptr CString -> IO [Text]+          go 0 _   = return []+          go n ptr = do+            cstring <- peek ptr+            (:) <$> cstringToText cstring+                    <*> go (n-1) (ptr `plusPtr` sizeOf cstring)++packFileNameArray :: [String] -> IO (Ptr CString)+packFileNameArray items = do+  let nitems = length items+  mem <- allocBytes $ nitems * (sizeOf (nullPtr :: CString))+  fill mem items+  return mem+    where fill            :: Ptr CString -> [String] -> IO ()+          fill _ []       = return ()+          fill ptr (x:xs) =+              do cstring <- stringToCString x+                 poke ptr cstring+                 fill (ptr `plusPtr` sizeOf cstring) xs++packZeroTerminatedFileNameArray :: [String] -> IO (Ptr CString)+packZeroTerminatedFileNameArray items = do+    let nitems = length items+    mem <- allocBytes $ (sizeOf (nullPtr :: CString)) * (nitems+1)+    fill mem items+    return mem+    where fill :: Ptr CString -> [String] -> IO ()+          fill ptr [] = poke ptr nullPtr+          fill ptr (x:xs) = do cstring <- stringToCString x+                               poke ptr cstring+                               fill (ptr `plusPtr` sizeOf cstring) xs++unpackZeroTerminatedFileNameArray :: Ptr CString -> IO [String]+unpackZeroTerminatedFileNameArray listPtr = go listPtr+    where go :: Ptr CString -> IO [String]+          go ptr = do+            cstring <- peek ptr+            if cstring == nullPtr+               then return []+               else (:) <$> cstringToString cstring+                        <*> go (ptr `plusPtr` sizeOf cstring)++unpackFileNameArrayWithLength :: Integral a =>+                                 a -> Ptr CString -> IO [String]+unpackFileNameArrayWithLength n ptr = go (fromIntegral n) ptr+    where go       :: Int -> Ptr CString -> IO [String]+          go 0 _   = return []+          go n ptr = do+            cstring <- peek ptr+            (:) <$> cstringToString cstring+                    <*> go (n-1) (ptr `plusPtr` sizeOf cstring)++foreign import ccall "g_strdup" g_strdup :: CString -> IO CString++-- We need to use the GLib allocator for constructing CStrings, since+-- the ownership of the string may be transferred to the GLib side,+-- which will free it with g_free.+stringToCString :: String -> IO CString+stringToCString str = withCString str g_strdup++cstringToString :: CString -> IO String+cstringToString = peekCString++foreign import ccall "g_strndup" g_strndup ::+    CString -> #{type gsize} -> IO CString++-- | Convert `Text` into a `CString`, using the GLib allocator.+textToCString :: Text -> IO CString+textToCString str = TF.withCStringLen str $ \(cstr, len) ->+  -- Because withCStringLen returns NULL for a zero-length Text, and+  -- g_strndup returns NULL for NULL, even if n==0.+  if cstr /= nullPtr+  then g_strndup cstr (fromIntegral len)+  else callocBytes 1++withTextCString :: Text -> (CString -> IO a) -> IO a+withTextCString text action = bracket (textToCString text) freeMem action++foreign import ccall "strlen" c_strlen ::+    CString -> IO (CSize)++cstringToText :: CString -> IO Text+cstringToText cstr = do+  len <- c_strlen cstr+  let cstrlen = (cstr, fromIntegral len)+  TF.peekCStringLen cstrlen++byteStringToCString :: ByteString -> IO CString+byteStringToCString bs = B.useAsCString bs g_strdup++cstringToByteString :: CString -> IO ByteString+cstringToByteString = B.packCString++packPtrArray :: [Ptr a] -> IO (Ptr (Ptr a))+packPtrArray items = do+  let nitems = length items+  mem <- allocBytes $ (sizeOf (nullPtr :: Ptr a)) * nitems+  fill mem items+  return mem+  where fill :: Ptr (Ptr a) -> [Ptr a] -> IO ()+        fill _ [] = return ()+        fill ptr (x:xs) = do poke ptr x+                             fill (ptr `plusPtr` sizeOf x) xs++packZeroTerminatedPtrArray :: [Ptr a] -> IO (Ptr (Ptr a))+packZeroTerminatedPtrArray items = do+  let nitems = length items+  mem <- allocBytes $ (sizeOf (nullPtr :: Ptr a)) * (nitems+1)+  fill mem items+  return mem+  where fill            :: Ptr (Ptr a) -> [Ptr a] -> IO ()+        fill ptr []     = poke ptr nullPtr+        fill ptr (x:xs) = do poke ptr x+                             fill (ptr `plusPtr` sizeOf x) xs++unpackPtrArrayWithLength :: Integral a => a -> Ptr (Ptr b) -> IO [Ptr b]+unpackPtrArrayWithLength n ptr = go (fromIntegral n) ptr+    where go       :: Int -> Ptr (Ptr a) -> IO [Ptr a]+          go 0 _   = return []+          go n ptr = (:) <$> peek ptr+                     <*> go (n-1) (ptr `plusPtr` sizeOf (nullPtr :: Ptr a))++unpackZeroTerminatedPtrArray :: Ptr (Ptr a) -> IO [Ptr a]+unpackZeroTerminatedPtrArray ptr = go ptr+    where go :: Ptr (Ptr a) -> IO [Ptr a]+          go ptr = do+            p <- peek ptr+            if p == nullPtr+            then return []+            else (p:) <$> go (ptr `plusPtr` sizeOf p)++mapZeroTerminatedCArray :: (Ptr a -> IO b) -> Ptr (Ptr a) -> IO ()+mapZeroTerminatedCArray f dataPtr+    | (dataPtr == nullPtr) = return ()+    | otherwise =+        do ptr <- peek dataPtr+           if ptr == nullPtr+           then return ()+           else do+             _ <- f ptr+             mapZeroTerminatedCArray f (dataPtr `plusPtr` sizeOf ptr)++packBlockArray :: Int -> [Ptr a] -> IO (Ptr a)+packBlockArray size items = do+  let nitems = length items+  mem <- allocBytes $ size * nitems+  fill mem items+  return mem+  where fill :: Ptr a -> [Ptr a] -> IO ()+        fill _ [] = return ()+        fill ptr (x:xs) = do memcpy ptr x size+                             fill (ptr `plusPtr` size) xs++foreign import ccall "g_memdup" g_memdup ::+    Ptr a -> CUInt -> IO (Ptr a)++unpackBlockArrayWithLength :: Integral a => Int -> a -> Ptr b -> IO [Ptr b]+unpackBlockArrayWithLength size n ptr = go size (fromIntegral n) ptr+    where go       :: Int -> Int -> Ptr b -> IO [Ptr b]+          go _ 0 _   = return []+          go size n ptr = do+            buf <- g_memdup ptr (fromIntegral size)+            (buf :) <$> go size (n-1) (ptr `plusPtr` size)++unpackBoxedArrayWithLength :: forall a b. (Integral a, BoxedObject b) =>+                              Int -> a -> Ptr b -> IO [Ptr b]+unpackBoxedArrayWithLength size n ptr = go size (fromIntegral n) ptr+    where go       :: Int -> Int -> Ptr b -> IO [Ptr b]+          go _ 0 _   = return []+          go size n ptr = do+            buf <- copyBoxedPtr ptr+            (buf :) <$> go size (n-1) (ptr `plusPtr` size)++mapCArrayWithLength :: (Storable a, Integral b) =>+                       b -> (a -> IO c) -> Ptr a -> IO ()+mapCArrayWithLength n f dataPtr+    | (dataPtr == nullPtr) = return ()+    | (n <= 0) = return ()+    | otherwise =+        do ptr <- peek dataPtr+           _ <- f ptr+           mapCArrayWithLength (n-1) f (dataPtr `plusPtr` sizeOf ptr)++mapGArray :: forall a b. Storable a => (a -> IO b) -> Ptr (GArray a) -> IO ()+mapGArray f array+    | (array == nullPtr) = return ()+    | otherwise =+        do dataPtr <- peek (castPtr array :: Ptr (Ptr a))+           nitems <- peek (array `plusPtr` sizeOf dataPtr)+           go dataPtr nitems+               where go :: Ptr a -> Int -> IO ()+                     go _ 0 = return ()+                     go ptr n = do+                       x <- peek ptr+                       _ <- f x+                       go (ptr `plusPtr` sizeOf x) (n-1)++mapPtrArray :: (Ptr a -> IO b) -> Ptr (GPtrArray (Ptr a)) -> IO ()+mapPtrArray f array = mapGArray f (castPtr array)++mapGList :: (Ptr a -> IO b) -> Ptr (GList (Ptr a)) -> IO ()+mapGList f glist+    | (glist == nullPtr) = return ()+    | otherwise =+        do ptr <- peek (castPtr glist)+           next <- peek (glist `plusPtr` sizeOf ptr)+           _ <- f ptr+           mapGList f next++mapGSList :: (Ptr a -> IO b) -> Ptr (GSList (Ptr a)) -> IO ()+mapGSList f gslist = mapGList f (castPtr gslist)
+ Data/GI/Base/BasicTypes.hs view
@@ -0,0 +1,215 @@+{-# LANGUAGE ConstraintKinds, FlexibleContexts, FlexibleInstances,+  DeriveDataTypeable, TypeFamilies, ScopedTypeVariables #-}+#if !MIN_VERSION_base(4,8,0)+{-# LANGUAGE OverlappingInstances #-}+#endif+#if MIN_VERSION_base(4,9,0)+{-# LANGUAGE DataKinds, TypeOperators, UndecidableInstances #-}+#endif+-- | Basic types used in the bindings.+module Data.GI.Base.BasicTypes+    (+      -- * GType related+      module Data.GI.Base.GType         -- reexported for convenience++     -- * Memory management+    , ManagedPtr(..)+    , ManagedPtrNewtype+    , BoxedObject(..)+    , BoxedEnum(..)+    , BoxedFlags(..)+    , GObject(..)+    , WrappedPtr(..)+    , UnexpectedNullPointerReturn(..)+    , NullToNothing(..)++    -- * Basic GLib \/ GObject types+    , GVariant(..)+    , GParamSpec(..)++    , GArray(..)+    , GPtrArray(..)+    , GByteArray(..)+    , GHashTable(..)+    , GList(..)+    , g_list_free+    , GSList(..)+    , g_slist_free++    , IsGFlag++    , PtrWrapped(..)+    , GDestroyNotify+    ) where++#if !MIN_VERSION_base(4,8,0)+import Control.Applicative ((<$>))+#endif+import Control.Exception (Exception, catch)+import Control.Monad.IO.Class (MonadIO(..))+import Data.Coerce (Coercible)+import Data.IORef (IORef)+import Data.Proxy (Proxy)+import qualified Data.Text as T+import Data.Typeable (Typeable)+import Foreign.Ptr (Ptr, FunPtr)+import Foreign.ForeignPtr (ForeignPtr)++#if MIN_VERSION_base(4,9,0)+import GHC.TypeLits+#endif++import Data.GI.Base.GType++-- | Thin wrapper over `ForeignPtr`, supporting the extra notion of+-- `disowning`, that is, not running the finalizers associated with+-- the foreign ptr.+data ManagedPtr a = ManagedPtr {+      managedForeignPtr :: ForeignPtr a+    , managedPtrIsOwned :: IORef Bool+    }++-- | A constraint ensuring that the given type is coercible to a+-- ManagedPtr. It will hold for newtypes of the form+--+-- > newtype Foo = Foo (ManagedPtr Foo)+--+-- which is the typical shape of wrapped 'GObject's.+type ManagedPtrNewtype a = Coercible a (ManagedPtr ())+-- Notice that the Coercible here is to ManagedPtr (), instead of+-- "ManagedPtr a", which would be the most natural thing. Both are+-- representationally equivalent, so this is not a big deal. This is+-- to work around a problem in ghc 7.10:+-- https://ghc.haskell.org/trac/ghc/ticket/10715++-- | Wrapped boxed structures, identified by their `GType`.+class ManagedPtrNewtype a => BoxedObject a where+    boxedType :: a -> IO GType -- This should not use the value of its+                               -- argument.++-- | Enums with an associated `GType`.+class BoxedEnum a where+    boxedEnumType :: a -> IO GType++-- | Flags with an associated `GType`.+class BoxedFlags a where+    boxedFlagsType :: Proxy a -> IO GType++-- | Pointers to structs/unions without an associated `GType`.+class ManagedPtrNewtype a => WrappedPtr a where+    -- | Allocate a zero-initialized block of memory for the given type.+    wrappedPtrCalloc :: IO (Ptr a)+    -- | Make a copy of the given pointer.+    wrappedPtrCopy   :: Ptr a -> IO (Ptr a)+    -- | A pointer to a function for freeing the given pointer, or+    -- `Nothing` is the memory associated to the pointer does not need+    -- to be freed.+    wrappedPtrFree   :: Maybe (FunPtr (Ptr a -> IO ()))++-- | A wrapped `GObject`.+class ManagedPtrNewtype a => GObject a where+    -- | Whether the `GObject` is a descendent of <https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#GInitiallyUnowned GInitiallyUnowned>.+    gobjectIsInitiallyUnowned :: a -> Bool+    -- | The `GType` for this object.+    gobjectType :: a -> IO GType++-- Raise a more understandable type error whenever the `GObject a`+-- constraint is imposed on a type which has no such instance. This+-- helps in the common case where one passes a wrong type (such as+-- `Maybe Widget`) into a function with a `IsWidget a`+-- constraint. Without this type error, the resulting type error is+-- much less understandable, since GHC complains (at length) about a+-- missing type family instance for `ParentTypes`.+#if MIN_VERSION_base(4,9,0)+instance {-# OVERLAPPABLE #-}+    (TypeError ('Text "Type ‘" ':<>: 'ShowType a ':<>:+                'Text "’ does not descend from GObject."), ManagedPtrNewtype a)+    => GObject a where+    gobjectIsInitiallyUnowned = undefined+    gobjectType = undefined+#endif++-- | A common omission in the introspection data is missing (nullable)+-- annotations for return types, when they clearly are nullable. (A+-- common idiom is "Returns: valid value, or %NULL if something went+-- wrong.")+--+-- Haskell wrappers will raise this exception if the return value is+-- an unexpected `Foreign.Ptr.nullPtr`.+data UnexpectedNullPointerReturn =+    UnexpectedNullPointerReturn { nullPtrErrorMsg :: T.Text }+                                deriving (Show, Typeable)++instance Exception UnexpectedNullPointerReturn++type family UnMaybe a :: * where+    UnMaybe (Maybe a) = a+    UnMaybe a         = a++class NullToNothing a where+    -- | Some functions are not marked as having a nullable return type+    -- in the introspection data.  The result is that they currently do+    -- not return a Maybe type.  This functions lets you work around this+    -- in a way that will not break when the introspection data is fixed.+    --+    -- When you want to call a `someHaskellGIFunction` that may return null+    -- wrap the call like this.+    --+    -- > nullToNothing (someHaskellGIFunction x y)+    --+    -- The result will be a Maybe type even if the introspection data has+    -- not been fixed for `someHaskellGIFunction` yet.+    nullToNothing :: MonadIO m => IO a -> m (Maybe (UnMaybe a))++instance+#if MIN_VERSION_base(4,8,0)+    {-# OVERLAPPABLE #-}+#endif+    a ~ UnMaybe a => NullToNothing a where+        nullToNothing f = liftIO $+            (Just <$> f) `catch` (\(_::UnexpectedNullPointerReturn) -> return Nothing)++instance NullToNothing (Maybe a) where+    nullToNothing = liftIO++-- | A <https://developer.gnome.org/glib/stable/glib-GVariant.html GVariant>. See "Data.GI.Base.GVariant" for further methods.+newtype GVariant = GVariant (ManagedPtr GVariant)++-- | A <https://developer.gnome.org/gobject/stable/gobject-GParamSpec.html GParamSpec>. See "Data.GI.Base.GParamSpec" for further methods.+newtype GParamSpec = GParamSpec (ManagedPtr GParamSpec)++-- | An enum usable as a flag for a function.+class Enum a => IsGFlag a++-- | A <https://developer.gnome.org/glib/stable/glib-Arrays.html GArray>. Marshalling for this type is done in "Data.GI.Base.BasicConversions", it is mapped to a list on the Haskell side.+data GArray a = GArray (Ptr (GArray a))++-- | A <https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html GPtrArray>. Marshalling for this type is done in "Data.GI.Base.BasicConversions", it is mapped to a list on the Haskell side.+data GPtrArray a = GPtrArray (Ptr (GPtrArray a))++-- | A <https://developer.gnome.org/glib/stable/glib-Byte-Arrays.html GByteArray>. Marshalling for this type is done in "Data.GI.Base.BasicConversions", it is packed to a 'Data.ByteString.ByteString' on the Haskell side.+data GByteArray = GByteArray (Ptr GByteArray)++-- | A <https://developer.gnome.org/glib/stable/glib-Hash-Tables.html GHashTable>. It is mapped to a 'Data.Map.Map' on the Haskell side.+data GHashTable a b = GHashTable (Ptr (GHashTable a b))++-- | A <https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html GList>, mapped to a list on the Haskell side. Marshalling is done in "Data.GI.Base.BasicConversions".+data GList a = GList (Ptr (GList a))++-- | A <https://developer.gnome.org/glib/stable/glib-Singly-Linked-Lists.html GSList>, mapped to a list on the Haskell side. Marshalling is done in "Data.GI.Base.BasicConversions".+data GSList a = GSList (Ptr (GSList a))++-- | Some APIs, such as `GHashTable`, pass around scalar types+-- wrapped into a pointer. We encode such a type as follows.+newtype PtrWrapped a = PtrWrapped {unwrapPtr :: Ptr a}++-- | Destroy the memory associated with a given pointer.+type GDestroyNotify a = FunPtr (Ptr a -> IO ())++-- | Free the given 'GList'.+foreign import ccall "g_list_free" g_list_free ::+    Ptr (GList a) -> IO ()++-- | Free the given 'GSList'.+foreign import ccall "g_slist_free" g_slist_free ::+    Ptr (GSList a) -> IO ()
+ Data/GI/Base/Closure.hs view
@@ -0,0 +1,41 @@+-- Some helper functions to create closures.+module Data.GI.Base.Closure+    ( Closure(..)+    , newCClosure+    , noClosure+    ) where++import Foreign++import Data.GI.Base.BasicTypes+import Data.GI.Base.ManagedPtr (wrapBoxed)+import Data.GI.Base.Utils (safeFreeFunPtrPtr)++newtype Closure = Closure (ManagedPtr Closure)++noClosure :: Maybe Closure+noClosure = Nothing++foreign import ccall "g_closure_get_type" c_g_closure_get_type ::+    IO GType++instance BoxedObject Closure where+    boxedType _ = c_g_closure_get_type+++foreign import ccall "g_cclosure_new" g_cclosure_new+    :: FunPtr a -> Ptr () -> FunPtr c -> IO (Ptr Closure)++foreign import ccall "g_closure_ref" g_closure_ref+    :: Ptr Closure -> IO (Ptr Closure)++foreign import ccall "g_closure_sink" g_closure_sink+    :: Ptr Closure -> IO ()++newCClosure :: FunPtr a -> IO Closure+newCClosure ptr = do+  closure <- g_cclosure_new ptr nullPtr safeFreeFunPtrPtr+  -- The Haskell runtime will manage the memory associated to the+  -- closure, so ref and sink to let GLib know this.+  g_closure_ref closure >>= g_closure_sink+  wrapBoxed Closure closure
+ Data/GI/Base/Constructible.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE DataKinds, FlexibleInstances, MultiParamTypeClasses,+  UndecidableInstances, KindSignatures, TypeFamilies #-}+#if !MIN_VERSION_base(4,8,0)+{-# LANGUAGE OverlappingInstances #-}+#endif++-- | `Constructible` types are those for which `new` is+-- defined. Often these are `GObject`s, but it is possible to+-- construct new (zero-initialized) structures and unions too.++module Data.GI.Base.Constructible+    ( Constructible(..)+    ) where++import Control.Monad.IO.Class (MonadIO)++import Data.GI.Base.Attributes (AttrOp, AttrOpTag(..))+import Data.GI.Base.BasicTypes (GObject, ManagedPtr)+import Data.GI.Base.GObject (constructGObject)++-- | Constructible types, i.e. those which can be allocated by `new`.+class Constructible a (tag :: AttrOpTag) where+    new :: MonadIO m => (ManagedPtr a -> a) -> [AttrOp a tag] -> m a++-- | Default instance, assuming we have a `GObject`.+instance+#if MIN_VERSION_base(4,8,0)+    {-# OVERLAPPABLE #-}+#endif+    (GObject a, tag ~ 'AttrConstruct) => Constructible a tag where+        new = constructGObject
+ Data/GI/Base/GError.hsc view
@@ -0,0 +1,248 @@+{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables #-}++-- | To catch GError exceptions use the+-- catchGError* or handleGError* functions. They work in a similar+-- way to the standard 'Control.Exception.catch' and+-- 'Control.Exception.handle' functions.+--+-- To catch just a single specific error use 'catchGErrorJust' \/+-- 'handleGErrorJust'. To catch any error in a particular error domain+-- use 'catchGErrorJustDomain' \/ 'handleGErrorJustDomain'+--+-- For convenience, generated code also includes specialized variants+-- of 'catchGErrorJust' \/ 'handleGErrorJust' for each error type. For+-- example, for errors of type 'GI.GdkPixbuf.PixbufError' one could+-- invoke 'GI.GdkPixbuf.catchPixbufError' \/+-- 'GI.GdkPixbuf.handlePixbufError'. The definition is simply+--+-- > catchPixbufError :: IO a -> (PixbufError -> GErrorMessage -> IO a) -> IO a+-- > catchPixbufError = catchGErrorJustDomain+--+-- Notice that the type is suitably specialized, so only+-- errors of type 'GI.GdkPixbuf.PixbufError' will be caught.+module Data.GI.Base.GError+    (+    -- * Unpacking GError+    --+      GError(..)+    , gerrorDomain+    , gerrorCode+    , gerrorMessage++    , GErrorDomain+    , GErrorCode+    , GErrorMessage++    -- * Catching GError exceptions+    , catchGErrorJust+    , catchGErrorJustDomain++    , handleGErrorJust+    , handleGErrorJustDomain++    -- * Creating new 'GError's+    , gerrorNew++    -- * Implementation specific details+    -- | The following are used in the implementation+    -- of the bindings, and are in general not necessary for using the+    -- API.+    , GErrorClass(..)++    , propagateGError+    , checkGError++    ) where++#if __GLASGOW_HASKELL__ < 710+import Control.Applicative ((<$>))+#endif++import Foreign (poke, peek)+import Foreign.Ptr (Ptr, plusPtr, nullPtr)+import Foreign.C+import Control.Exception+import Data.Text (Text)+import qualified Data.Text as T+import Data.Typeable (Typeable)+import Data.Int+import Data.Word++import System.IO.Unsafe (unsafePerformIO)++import Data.GI.Base.BasicTypes (BoxedObject(..), GType(..), ManagedPtr)+import Data.GI.Base.BasicConversions (withTextCString, cstringToText)+import Data.GI.Base.ManagedPtr (wrapBoxed, withManagedPtr)+import Data.GI.Base.Utils (allocMem, freeMem)++#include <glib.h>++-- | A GError, consisting of a domain, code and a human readable+-- message. These can be accessed by 'gerrorDomain', 'gerrorCode' and+-- 'gerrorMessage' below.+newtype GError = GError (ManagedPtr GError)+    deriving (Typeable)++instance Show GError where+    show gerror = unsafePerformIO $ do+                       code <- gerrorCode gerror+                       message <- gerrorMessage gerror+                       return $ T.unpack message ++ " (" ++ show code ++ ")"++instance Exception GError++foreign import ccall "g_error_get_type" g_error_get_type :: IO GType++instance BoxedObject GError where+    boxedType _ = g_error_get_type++-- | A GQuark.+type GQuark = #type GQuark++-- | A code used to identify the "namespace" of the error. Within each error+--   domain all the error codes are defined in an enumeration. Each gtk\/gnome+--   module that uses GErrors has its own error domain. The rationale behind+--   using error domains is so that each module can organise its own error codes+--   without having to coordinate on a global error code list.+type GErrorDomain  = GQuark++-- | A code to identify a specific error within a given 'GErrorDomain'. Most of+--   time you will not need to deal with this raw code since there is an+--   enumeration type for each error domain. Of course which enumeration to use+--   depends on the error domain, but if you use 'catchGErrorJustDomain' or+--   'handleGErrorJustDomain', this is worked out for you automatically.+type GErrorCode = #type gint++-- | A human readable error message.+type GErrorMessage = Text++foreign import ccall "g_error_new_literal" g_error_new_literal ::+    GQuark -> GErrorCode -> CString -> IO (Ptr GError)++-- | Create a new 'GError'.+gerrorNew :: GErrorDomain -> GErrorCode -> GErrorMessage -> IO GError+gerrorNew domain code message =+    withTextCString message $ \cstring ->+        g_error_new_literal domain code cstring >>= wrapBoxed GError++-- | Return the domain for the given `GError`. This is a GQuark, a+-- textual representation can be obtained with+-- `GI.GLib.quarkToString`.+gerrorDomain :: GError -> IO GQuark+gerrorDomain gerror =+    withManagedPtr gerror $ \ptr ->+      peek $ ptr `plusPtr` #{offset GError, domain}++-- | The numeric code for the given `GError`.+gerrorCode :: GError -> IO GErrorCode+gerrorCode gerror =+    withManagedPtr gerror $ \ptr ->+        peek $ ptr `plusPtr` #{offset GError, code}++-- | A text message describing the `GError`.+gerrorMessage :: GError -> IO GErrorMessage+gerrorMessage gerror =+    withManagedPtr gerror $ \ptr ->+      (peek $ ptr `plusPtr` #{offset GError, message}) >>= cstringToText++-- | Each error domain's error enumeration type should be an instance of this+--   class. This class helps to hide the raw error and domain codes from the+--   user.+--+-- Example for 'GI.GdkPixbuf.PixbufError':+--+-- > instance GErrorClass PixbufError where+-- >   gerrorClassDomain _ = "gdk-pixbuf-error-quark"+--+class Enum err => GErrorClass err where+  gerrorClassDomain :: err -> Text   -- ^ This must not use the value of its+                                     -- parameter so that it is safe to pass+                                     -- 'undefined'.++foreign import ccall unsafe "g_quark_try_string" g_quark_try_string ::+    CString -> IO GQuark++-- | Given the string representation of an error domain returns the+--   corresponding error quark.+gErrorQuarkFromDomain :: Text -> IO GQuark+gErrorQuarkFromDomain domain = withTextCString domain g_quark_try_string++-- | This will catch just a specific GError exception. If you need to catch a+--   range of related errors, 'catchGErrorJustDomain' is probably more+--   appropriate. Example:+--+-- > do image <- catchGErrorJust PixbufErrorCorruptImage+-- >               loadImage+-- >               (\errorMessage -> do log errorMessage+-- >                                    return mssingImagePlaceholder)+--+catchGErrorJust :: GErrorClass err => err  -- ^ The error to catch+                -> IO a                    -- ^ The computation to run+                -> (GErrorMessage -> IO a) -- ^ Handler to invoke if+                                           -- an exception is raised+                -> IO a+catchGErrorJust code action handler = do+  domainQuark <- gErrorQuarkFromDomain $ gerrorClassDomain code+  catch action (handler' domainQuark)+  where handler' quark gerror = do+          domain <- gerrorDomain gerror+          code' <- gerrorCode gerror+          if domain == quark && code' == (fromIntegral . fromEnum) code+          then gerrorMessage gerror >>= handler+          else throw gerror -- Pass it on++-- | Catch all GErrors from a particular error domain. The handler function+--   should just deal with one error enumeration type. If you need to catch+--   errors from more than one error domain, use this function twice with an+--   appropriate handler functions for each.+--+-- > catchGErrorJustDomain+-- >   loadImage+-- >   (\err message -> case err of+-- >       PixbufErrorCorruptImage -> ...+-- >       PixbufErrorInsufficientMemory -> ...+-- >       PixbufErrorUnknownType -> ...+-- >       _ -> ...)+--+catchGErrorJustDomain :: forall err a. GErrorClass err =>+                         IO a        -- ^ The computation to run+                      -> (err -> GErrorMessage -> IO a) -- ^ Handler to invoke if an exception is raised+                      -> IO a+catchGErrorJustDomain action handler = do+  domainQuark <- gErrorQuarkFromDomain $ gerrorClassDomain (undefined::err)+  catch action (handler' domainQuark)+  where handler' quark gerror = do+          domain <- gerrorDomain gerror+          if domain == quark+          then do+            code <- (toEnum . fromIntegral) <$> gerrorCode gerror+            msg <- gerrorMessage gerror+            handler code msg+          else throw gerror++-- | A verson of 'handleGErrorJust' with the arguments swapped around.+handleGErrorJust :: GErrorClass err => err -> (GErrorMessage -> IO a) -> IO a -> IO a+handleGErrorJust code = flip (catchGErrorJust code)++-- | A verson of 'catchGErrorJustDomain' with the arguments swapped around.+handleGErrorJustDomain :: GErrorClass err => (err -> GErrorMessage -> IO a) -> IO a -> IO a+handleGErrorJustDomain = flip catchGErrorJustDomain++-- | Run the given function catching possible 'GError's in its+-- execution. If a 'GError' is emitted this throws the corresponding+-- exception.+propagateGError :: (Ptr (Ptr GError) -> IO a) -> IO a+propagateGError f = checkGError f throw++-- | Like 'propagateGError', but allows to specify a custom handler+-- instead of just throwing the exception.+checkGError :: (Ptr (Ptr GError) -> IO a) -> (GError -> IO a) -> IO a+checkGError f handler = do+  gerrorPtr <- allocMem+  poke gerrorPtr nullPtr+  result <- f gerrorPtr+  gerror <- peek gerrorPtr+  freeMem gerrorPtr+  if gerror /= nullPtr+  then wrapBoxed GError gerror >>= handler+  else return result
+ Data/GI/Base/GHashTable.hsc view
@@ -0,0 +1,68 @@+{- | Machinery for some basic support of `GHashTable`.++The GLib `GHashTable` implementation requires two things: we need to+"pack" a datatype into a pointer (for datatypes that are represented+by pointers this is the trivial operation, for integers it is not, and+GLib has some helper macros).++We also need to be able to hash and check for equality different+datatypes.+-}+module Data.GI.Base.GHashTable+    ( GHashFunc+    , GEqualFunc++    , gDirectHash+    , gDirectEqual+    , ptrPackPtr+    , ptrUnpackPtr++    , gStrHash+    , gStrEqual+    , cstringPackPtr+    , cstringUnpackPtr+    ) where++import Data.Int+import Data.Word++import Foreign.C+import Foreign.Ptr (Ptr, castPtr, FunPtr)++import Data.GI.Base.BasicTypes (PtrWrapped(..))++#include <glib-object.h>++-- | A pointer to a hashing function on the C side.+type GHashFunc a = FunPtr (PtrWrapped a -> IO #{type guint})++-- | A pointer to an equality checking function on the C side.+type GEqualFunc a = FunPtr (PtrWrapped a -> PtrWrapped a -> IO #{type gboolean})++-- | Compute the hash for a `Ptr`.+foreign import ccall "&g_direct_hash" gDirectHash :: GHashFunc (Ptr a)++-- | Check whether two pointers are equal.+foreign import ccall "&g_direct_equal" gDirectEqual :: GEqualFunc (Ptr a)++-- | Pack a `Ptr` into a `PtrWrapped` `Ptr`.+ptrPackPtr :: Ptr a -> PtrWrapped (Ptr a)+ptrPackPtr = PtrWrapped . castPtr++-- | Extract a `Ptr` from a `PtrWrapped` `Ptr`.+ptrUnpackPtr :: PtrWrapped (Ptr a) -> Ptr a+ptrUnpackPtr = castPtr . unwrapPtr++-- | Compute the hash for a `CString`.+foreign import ccall "&g_str_hash" gStrHash :: GHashFunc CString++-- | Check whether two `CString`s are equal.+foreign import ccall "&g_str_equal" gStrEqual :: GEqualFunc CString++-- | Pack a `CString` into a `Ptr` than can go into a `GHashTable`.+cstringPackPtr :: CString -> PtrWrapped CString+cstringPackPtr = ptrPackPtr++-- | Extract a `CString` wrapped into a `Ptr` coming from a `GHashTable`.+cstringUnpackPtr :: PtrWrapped CString -> CString+cstringUnpackPtr = ptrUnpackPtr
+ Data/GI/Base/GObject.hsc view
@@ -0,0 +1,98 @@+{-# LANGUAGE ScopedTypeVariables, DataKinds, TypeFamilies #-}++module Data.GI.Base.GObject+    ( constructGObject+    , new'+    ) where++import Control.Monad.IO.Class (MonadIO, liftIO)+import Data.Proxy (Proxy(..))++import Foreign.C (CUInt(..), CString, newCString)+import Foreign++import Data.GI.Base.Attributes (AttrOp(..), AttrOpTag(..), AttrLabelProxy,+                                attrConstruct)+import Data.GI.Base.BasicTypes (GType(..), GObject(..), ManagedPtr)+import Data.GI.Base.GValue (GValue(..), GValueConstruct(..))+import Data.GI.Base.ManagedPtr (withManagedPtr, touchManagedPtr, wrapObject)+import Data.GI.Base.Overloading (ResolveAttribute)++#include <glib-object.h>++foreign import ccall "dbg_g_object_newv" g_object_newv ::+    GType -> CUInt -> Ptr a -> IO (Ptr b)++-- | Construct a GObject given the constructor and a list of settable+-- attributes.+constructGObject :: forall o m. (GObject o, MonadIO m)+    => (ManagedPtr o -> o)+    -> [AttrOp o 'AttrConstruct]+    -> m o+constructGObject constructor attrs = liftIO $ do+  props <- mapM construct attrs+  doConstructGObject constructor props+  where+    resolve :: AttrLabelProxy attr -> Proxy (ResolveAttribute attr o)+    resolve _ = Proxy++    construct :: AttrOp o 'AttrConstruct ->+                 IO (GValueConstruct o)+    construct (attr := x) = attrConstruct (resolve attr) x+    construct (attr :=> x) = x >>= attrConstruct (resolve attr)++-- | Construct the `GObject` given the list of `GValueConstruct`s.+doConstructGObject :: forall o m. (GObject o, MonadIO m)+                      => (ManagedPtr o -> o) -> [GValueConstruct o] -> m o+doConstructGObject constructor props = liftIO $ do+  let nprops = length props+  params <- mallocBytes (nprops*gparameterSize)+  fill params props+  gtype <- gobjectType (undefined :: o)+  result <- g_object_newv gtype (fromIntegral nprops) params+  freeStrings nprops params+  free params+  -- Make sure that the GValues defining the GProperties are still+  -- alive at this point (so, in particular, they are still alive when+  -- g_object_newv is called). Without this the GHC garbage collector+  -- may free the GValues before g_object_newv is called, which will+  -- unref the referred to objects, which may drop the last reference+  -- to the contained objects. g_object_newv then tries to access the+  -- (now invalid) contents of the GValue, and mayhem ensues.+  mapM_ (touchManagedPtr . deconstructGValue) props+  wrapObject constructor (result :: Ptr o)++  where+    deconstructGValue :: GValueConstruct o -> GValue+    deconstructGValue (GValueConstruct _ v) = v++    gvalueSize = #size GValue+    gparameterSize = #size GParameter++    -- Fill the given memory address with the contents of the array of+    -- GParameters.+    fill :: Ptr () -> [GValueConstruct o] -> IO ()+    fill _ [] = return ()+    fill dataPtr ((GValueConstruct str gvalue):xs) =+        do cstr <- newCString str+           poke (castPtr dataPtr) cstr+           withManagedPtr gvalue $ \gvalueptr ->+               copyBytes (dataPtr `plusPtr` sizeOf nullPtr) gvalueptr gvalueSize+           fill (dataPtr `plusPtr` gparameterSize) xs++    -- Free the strings in the GParameter array (the GValues will be+    -- freed separately).+    freeStrings :: Int -> Ptr () -> IO ()+    freeStrings 0 _ = return ()+    freeStrings n dataPtr =+        do cstr <- peek (castPtr dataPtr) :: IO CString+           free cstr+           freeStrings (n-1) (dataPtr `plusPtr` gparameterSize)++-- | Construct the given `GObject`, given a set of actions+-- constructing desired `GValue`s to set at construction time.+new' :: (MonadIO m, GObject o) =>+        (ManagedPtr o -> o) -> [IO (GValueConstruct o)] -> m o+new' constructor actions = do+  props <- liftIO $ sequence (actions)+  doConstructGObject constructor props
+ Data/GI/Base/GParamSpec.hsc view
@@ -0,0 +1,52 @@+module Data.GI.Base.GParamSpec+    ( noGParamSpec++    , wrapGParamSpecPtr+    , newGParamSpecFromPtr+    , unrefGParamSpec+    , disownGParamSpec+    ) where++import Foreign.Ptr+import Control.Monad (void)++import Data.GI.Base.ManagedPtr (newManagedPtr', withManagedPtr, disownManagedPtr)+import Data.GI.Base.BasicTypes (GParamSpec(..))++#include <glib-object.h>++noGParamSpec :: Maybe GParamSpec+noGParamSpec = Nothing++foreign import ccall "g_param_spec_ref_sink" g_param_spec_ref_sink ::+    Ptr GParamSpec -> IO (Ptr GParamSpec)+foreign import ccall "g_param_spec_ref" g_param_spec_ref ::+    Ptr GParamSpec -> IO (Ptr GParamSpec)+foreign import ccall "g_param_spec_unref" g_param_spec_unref ::+    Ptr GParamSpec -> IO ()+foreign import ccall "&g_param_spec_unref" ptr_to_g_param_spec_unref ::+    FunPtr (Ptr GParamSpec -> IO ())++-- | Take ownership of a ParamSpec passed in 'Ptr'.+wrapGParamSpecPtr :: Ptr GParamSpec -> IO GParamSpec+wrapGParamSpecPtr ptr = do+  void $ g_param_spec_ref_sink ptr+  fPtr <- newManagedPtr' ptr_to_g_param_spec_unref ptr+  return $! GParamSpec fPtr++-- | Construct a Haskell wrapper for the given 'GParamSpec', without+-- assuming ownership.+newGParamSpecFromPtr :: Ptr GParamSpec -> IO GParamSpec+newGParamSpecFromPtr ptr = do+  fPtr <- g_param_spec_ref ptr >>= newManagedPtr' ptr_to_g_param_spec_unref+  return $! GParamSpec fPtr++-- | Remove a reference to the given 'GParamSpec'.+unrefGParamSpec :: GParamSpec -> IO ()+unrefGParamSpec ps = withManagedPtr ps g_param_spec_unref++-- | Disown a `GParamSpec`, i.e. do not longer unref the associated+-- foreign `GParamSpec` when the Haskell `GParamSpec` gets garbage+-- collected.+disownGParamSpec :: GParamSpec -> IO (Ptr GParamSpec)+disownGParamSpec = disownManagedPtr
+ Data/GI/Base/GType.hsc view
@@ -0,0 +1,142 @@+-- | Basic `GType`s.+module Data.GI.Base.GType+    ( GType(..)+    , CGType++    , gtypeName++    , gtypeString+    , gtypePointer+    , gtypeInt+    , gtypeUInt+    , gtypeLong+    , gtypeULong+    , gtypeInt64+    , gtypeUInt64+    , gtypeFloat+    , gtypeDouble+    , gtypeBoolean+    , gtypeGType+    , gtypeStrv+    , gtypeBoxed+    , gtypeObject+    , gtypeVariant+    , gtypeByteArray+    , gtypeInvalid+    ) where++import Data.Word+import Foreign.C.String (CString, peekCString)++#include <glib-object.h>++-- | A type identifier in the GLib type system. This is the low-level+-- type associated with the representation in memory, when using this+-- on the Haskell side use `GType` below.+type CGType = #type GType++-- | A newtype for use on the haskell side.+newtype GType = GType {gtypeToCGType :: CGType}++foreign import ccall "g_type_name" g_type_name :: GType -> IO CString++-- | Get the name assigned to the given `GType`.+gtypeName :: GType -> IO String+gtypeName gtype = g_type_name gtype >>= peekCString++{-| [Note: compile-time vs run-time GTypes]++Notice that there are two types of GType's: the fundamental ones,+which are created with G_TYPE_MAKE_FUNDAMENTAL(n) and always have the+same runtime representation, and the ones that are registered in the+GObject type system at runtime, and whose `CGType` may change for each+program run (and generally does).++For the first type it is safe to use hsc to read the numerical values+of the CGType at compile type, but for the second type it is essential+to call the corresponding _get_type() function at runtime, and not use+the value of the corresponding "constant" at compile time via hsc.+-}++{- Fundamental types -}++-- | `GType` of strings.+gtypeString :: GType+gtypeString = GType #const G_TYPE_STRING++-- | `GType` of pointers.+gtypePointer :: GType+gtypePointer = GType #const G_TYPE_POINTER++-- | `GType` for signed integers (`gint` or `gint32`).+gtypeInt :: GType+gtypeInt = GType #const G_TYPE_INT++-- | `GType` for unsigned integers (`guint` or `guint32`).+gtypeUInt :: GType+gtypeUInt = GType #const G_TYPE_UINT++-- | `GType` for `glong`.+gtypeLong :: GType+gtypeLong = GType #const G_TYPE_LONG++-- | `GType` for `gulong`.+gtypeULong :: GType+gtypeULong = GType #const G_TYPE_ULONG++-- | `GType` for signed 64 bit integers.+gtypeInt64 :: GType+gtypeInt64 = GType #const G_TYPE_INT64++-- | `GType` for unsigned 64 bit integers.+gtypeUInt64 :: GType+gtypeUInt64 = GType #const G_TYPE_UINT64++-- | `GType` for floating point values.+gtypeFloat :: GType+gtypeFloat = GType #const G_TYPE_FLOAT++-- | `GType` for gdouble.+gtypeDouble :: GType+gtypeDouble = GType #const G_TYPE_DOUBLE++-- | `GType` corresponding to gboolean.+gtypeBoolean :: GType+gtypeBoolean = GType #const G_TYPE_BOOLEAN++-- | `GType` corresponding to a `BoxedObject`.+gtypeBoxed :: GType+gtypeBoxed = GType #const G_TYPE_BOXED++-- | `GType` corresponding to a `GObject`.+gtypeObject :: GType+gtypeObject = GType #const G_TYPE_OBJECT++-- | An invalid `GType` used as error return value in some functions+-- which return a `GType`.+gtypeInvalid :: GType+gtypeInvalid = GType #const G_TYPE_INVALID++-- | The `GType` corresponding to a `GVariant`.+gtypeVariant :: GType+gtypeVariant = GType #const G_TYPE_VARIANT++{- Run-time types -}++foreign import ccall "g_gtype_get_type" g_gtype_get_type :: CGType++-- | `GType` corresponding to a `GType` itself.+gtypeGType :: GType+gtypeGType = GType g_gtype_get_type++foreign import ccall "g_strv_get_type" g_strv_get_type :: CGType++-- | `GType` for a NULL terminated array of strings.+gtypeStrv :: GType+gtypeStrv = GType g_strv_get_type++foreign import ccall "g_byte_array_get_type" g_byte_array_get_type :: CGType++-- | `GType` for a boxed type holding a `GByteArray`.+gtypeByteArray :: GType+gtypeByteArray = GType g_byte_array_get_type
+ Data/GI/Base/GValue.hsc view
@@ -0,0 +1,378 @@+{-# LANGUAGE FlexibleInstances #-}+module Data.GI.Base.GValue+    ( GValue(..)+    , IsGValue(..)++    , newGValue         -- Build a new, empty, GValue of the given type+    , buildGValue       -- Build a new GValue and initialize to the given value+    , noGValue++    , GValueConstruct(..)++    , set_string+    , get_string+    , set_pointer+    , get_pointer+    , set_int+    , get_int+    , set_uint+    , get_uint+    , set_long+    , get_long+    , set_ulong+    , get_ulong+    , set_int32+    , get_int32+    , set_uint32+    , get_uint32+    , set_int64+    , get_int64+    , set_uint64+    , get_uint64+    , set_float+    , get_float+    , set_double+    , get_double+    , set_boolean+    , get_boolean+    , set_gtype+    , get_gtype+    , set_object+    , get_object+    , set_boxed+    , get_boxed+    , set_variant+    , get_variant+    , set_enum+    , get_enum+    , set_flags+    , get_flags+    ) where++#include <glib-object.h>++#if !MIN_VERSION_base(4,8,0)+import Control.Applicative ((<$>))+#endif++import Data.Coerce (coerce)+import Data.Word+import Data.Int+import Data.Text (Text, pack, unpack)++import Foreign.C.Types (CInt(..), CUInt(..), CFloat(..), CDouble(..),+                        CLong(..), CULong(..))+import Foreign.C.String (CString)+import Foreign.Ptr (Ptr, nullPtr)++import Data.GI.Base.BasicTypes+import Data.GI.Base.BasicConversions (cstringToText, textToCString)+import Data.GI.Base.ManagedPtr+import Data.GI.Base.Utils (callocBytes, freeMem)++newtype GValue = GValue (ManagedPtr GValue)++noGValue :: Maybe GValue+noGValue = Nothing++foreign import ccall unsafe "g_value_get_type" c_g_value_get_type ::+    IO CGType++instance BoxedObject GValue where+    boxedType _ = GType <$> c_g_value_get_type++foreign import ccall "g_value_init" g_value_init ::+    Ptr GValue -> CGType -> IO (Ptr GValue)++-- | A type holding a `GValue` with an associated label. It is+-- parameterized by a phantom type encoding the target type for the+-- `GValue` (useful when constructing properties).+data GValueConstruct o = GValueConstruct String GValue++newGValue :: GType -> IO GValue+newGValue (GType gtype) = do+  gvptr <- callocBytes #size GValue+  _ <- g_value_init gvptr gtype+  gv <- wrapBoxed GValue gvptr+  return $! gv++-- Build a new GValue and set the initial value, just for convenience+buildGValue :: GType -> (GValue -> a -> IO ()) -> a -> IO GValue+buildGValue gtype setter val = do+  gv <- newGValue gtype+  setter gv val+  return gv++class IsGValue a where+    toGValue :: a -> IO GValue+    fromGValue :: GValue -> IO a++instance IsGValue (Maybe String) where+    toGValue = buildGValue gtypeString set_string . fmap pack+    fromGValue v = (fmap unpack) <$> get_string v++instance IsGValue (Maybe Text) where+    toGValue = buildGValue gtypeString set_string+    fromGValue = get_string++instance IsGValue (Ptr a) where+    toGValue = buildGValue gtypePointer set_pointer+    fromGValue = get_pointer++instance IsGValue Int32 where+    toGValue = buildGValue gtypeInt set_int32+    fromGValue = get_int32++instance IsGValue Word32 where+    toGValue = buildGValue gtypeUInt set_uint32+    fromGValue = get_uint32++instance IsGValue CInt where+    toGValue = buildGValue gtypeInt set_int+    fromGValue = get_int++instance IsGValue CUInt where+    toGValue = buildGValue gtypeUInt set_uint+    fromGValue = get_uint++instance IsGValue CLong where+    toGValue = buildGValue gtypeLong set_long+    fromGValue = get_long++instance IsGValue CULong where+    toGValue = buildGValue gtypeULong set_ulong+    fromGValue = get_ulong++instance IsGValue Int64 where+    toGValue = buildGValue gtypeInt64 set_int64+    fromGValue = get_int64++instance IsGValue Word64 where+    toGValue = buildGValue gtypeUInt64 set_uint64+    fromGValue = get_uint64++instance IsGValue Float where+    toGValue = buildGValue gtypeFloat set_float+    fromGValue = get_float++instance IsGValue Double where+    toGValue = buildGValue gtypeDouble set_double+    fromGValue = get_double++instance IsGValue Bool where+    toGValue = buildGValue gtypeBoolean set_boolean+    fromGValue = get_boolean++instance IsGValue GType where+    toGValue = buildGValue gtypeGType set_gtype+    fromGValue = get_gtype++foreign import ccall "g_value_set_string" _set_string ::+    Ptr GValue -> CString -> IO ()+foreign import ccall "g_value_get_string" _get_string ::+    Ptr GValue -> IO CString++set_string :: GValue -> Maybe Text -> IO ()+set_string gv maybeStr =+    withManagedPtr gv $ \ptr -> do+      cstr <- case maybeStr of+                Just str -> textToCString str+                Nothing -> return nullPtr+      _set_string ptr cstr+      freeMem cstr++get_string :: GValue -> IO (Maybe Text)+get_string gv = withManagedPtr gv $ \gvptr -> do+                  cstr <- _get_string gvptr+                  if cstr /= nullPtr+                  then Just <$> cstringToText cstr+                  else return Nothing++foreign import ccall unsafe "g_value_set_pointer" _set_pointer ::+    Ptr GValue -> Ptr a -> IO ()+foreign import ccall unsafe "g_value_get_pointer" _get_pointer ::+    Ptr GValue -> IO (Ptr b)++set_pointer :: GValue -> Ptr a -> IO ()+set_pointer gv ptr = withManagedPtr gv $ flip _set_pointer ptr++get_pointer :: GValue -> IO (Ptr b)+get_pointer gv = withManagedPtr gv _get_pointer++foreign import ccall unsafe "g_value_set_int" _set_int ::+    Ptr GValue -> CInt -> IO ()+foreign import ccall unsafe "g_value_get_int" _get_int ::+    Ptr GValue -> IO CInt++set_int32 :: GValue -> Int32 -> IO ()+set_int32 gv n = withManagedPtr gv $ flip _set_int (coerce n)++get_int32 :: GValue -> IO Int32+get_int32 gv = coerce <$> withManagedPtr gv _get_int++set_int :: GValue -> CInt -> IO ()+set_int gv n = withManagedPtr gv $ flip _set_int n++get_int :: GValue -> IO CInt+get_int gv = withManagedPtr gv _get_int++foreign import ccall unsafe "g_value_set_uint" _set_uint ::+    Ptr GValue -> CUInt -> IO ()+foreign import ccall unsafe "g_value_get_uint" _get_uint ::+    Ptr GValue -> IO CUInt++set_uint32 :: GValue -> Word32 -> IO ()+set_uint32 gv n = withManagedPtr gv $ flip _set_uint (coerce n)++get_uint32 :: GValue -> IO Word32+get_uint32 gv = coerce <$> withManagedPtr gv _get_uint++set_uint :: GValue -> CUInt -> IO ()+set_uint gv n = withManagedPtr gv $ flip _set_uint n++get_uint :: GValue -> IO CUInt+get_uint gv = withManagedPtr gv _get_uint++foreign import ccall unsafe "g_value_set_long" _set_long ::+    Ptr GValue -> CLong -> IO ()+foreign import ccall unsafe "g_value_get_long" _get_long ::+    Ptr GValue -> IO CLong++set_long :: GValue -> CLong -> IO ()+set_long gv n = withManagedPtr gv $ flip _set_long n++get_long :: GValue -> IO CLong+get_long gv = withManagedPtr gv _get_long++foreign import ccall unsafe "g_value_set_ulong" _set_ulong ::+    Ptr GValue -> CULong -> IO ()+foreign import ccall unsafe "g_value_get_ulong" _get_ulong ::+    Ptr GValue -> IO CULong++set_ulong :: GValue -> CULong -> IO ()+set_ulong gv n = withManagedPtr gv $ flip _set_ulong n++get_ulong :: GValue -> IO CULong+get_ulong gv = withManagedPtr gv _get_ulong++foreign import ccall unsafe "g_value_set_int64" _set_int64 ::+    Ptr GValue -> Int64 -> IO ()+foreign import ccall unsafe "g_value_get_int64" _get_int64 ::+    Ptr GValue -> IO Int64++set_int64 :: GValue -> Int64 -> IO ()+set_int64 gv n = withManagedPtr gv $ flip _set_int64 n++get_int64 :: GValue -> IO Int64+get_int64 gv = withManagedPtr gv _get_int64++foreign import ccall unsafe "g_value_set_uint64" _set_uint64 ::+    Ptr GValue -> Word64 -> IO ()+foreign import ccall unsafe "g_value_get_uint64" _get_uint64 ::+    Ptr GValue -> IO Word64++set_uint64 :: GValue -> Word64 -> IO ()+set_uint64 gv n = withManagedPtr gv $ flip _set_uint64 n++get_uint64 :: GValue -> IO Word64+get_uint64 gv = withManagedPtr gv _get_uint64++foreign import ccall unsafe "g_value_set_float" _set_float ::+    Ptr GValue -> CFloat -> IO ()+foreign import ccall unsafe "g_value_get_float" _get_float ::+    Ptr GValue -> IO CFloat++set_float :: GValue -> Float -> IO ()+set_float gv f = withManagedPtr gv $ flip _set_float (realToFrac f)++get_float :: GValue -> IO Float+get_float gv = realToFrac <$> withManagedPtr gv _get_float++foreign import ccall unsafe "g_value_set_double" _set_double ::+    Ptr GValue -> CDouble -> IO ()+foreign import ccall unsafe "g_value_get_double" _get_double ::+    Ptr GValue -> IO CDouble++set_double :: GValue -> Double -> IO ()+set_double gv d = withManagedPtr gv $ flip _set_double (realToFrac d)++get_double :: GValue -> IO Double+get_double gv = realToFrac <$> withManagedPtr gv _get_double++foreign import ccall unsafe "g_value_set_boolean" _set_boolean ::+    Ptr GValue -> CInt -> IO ()+foreign import ccall unsafe "g_value_get_boolean" _get_boolean ::+    Ptr GValue -> IO CInt++set_boolean :: GValue -> Bool -> IO ()+set_boolean gv b = withManagedPtr gv $ \ptr ->+                   _set_boolean ptr (fromIntegral $ fromEnum b)++get_boolean :: GValue -> IO Bool+get_boolean gv = withManagedPtr gv $ \ptr -> (/= 0) <$> _get_boolean ptr++foreign import ccall unsafe "g_value_set_gtype" _set_gtype ::+    Ptr GValue -> CGType -> IO ()+foreign import ccall unsafe "g_value_get_gtype" _get_gtype ::+    Ptr GValue -> IO CGType++set_gtype :: GValue -> GType -> IO ()+set_gtype gv (GType g) = withManagedPtr gv $ \ptr -> _set_gtype ptr g++get_gtype :: GValue -> IO GType+get_gtype gv = GType <$> withManagedPtr gv _get_gtype++foreign import ccall "g_value_set_object" _set_object ::+    Ptr GValue -> Ptr a -> IO ()+foreign import ccall "g_value_get_object" _get_object ::+    Ptr GValue -> IO (Ptr a)++set_object :: GObject a => GValue -> Ptr a -> IO ()+set_object gv o = withManagedPtr gv $ flip _set_object o++get_object :: GObject b => GValue -> IO (Ptr b)+get_object gv = withManagedPtr gv _get_object++foreign import ccall "g_value_set_boxed" _set_boxed ::+    Ptr GValue -> Ptr a -> IO ()+foreign import ccall "g_value_get_boxed" _get_boxed ::+    Ptr GValue -> IO (Ptr b)++set_boxed :: GValue -> Ptr a -> IO ()+set_boxed gv b = withManagedPtr gv $ flip _set_boxed b++get_boxed :: GValue -> IO (Ptr b)+get_boxed gv = withManagedPtr gv _get_boxed++foreign import ccall "g_value_set_variant" _set_variant ::+    Ptr GValue -> Ptr GVariant -> IO ()+foreign import ccall "g_value_get_variant" _get_variant ::+    Ptr GValue -> IO (Ptr GVariant)++set_variant :: GValue -> Ptr GVariant -> IO ()+set_variant gv v = withManagedPtr gv $ flip _set_variant v++get_variant :: GValue -> IO (Ptr GVariant)+get_variant gv = withManagedPtr gv _get_variant++foreign import ccall unsafe "g_value_set_enum" _set_enum ::+    Ptr GValue -> CUInt -> IO ()+foreign import ccall unsafe "g_value_get_enum" _get_enum ::+    Ptr GValue -> IO CUInt++set_enum :: GValue -> CUInt -> IO ()+set_enum gv e = withManagedPtr gv $ flip _set_enum e++get_enum :: GValue -> IO CUInt+get_enum gv = withManagedPtr gv _get_enum++foreign import ccall unsafe "g_value_set_flags" _set_flags ::+    Ptr GValue -> CUInt -> IO ()+foreign import ccall unsafe "g_value_get_flags" _get_flags ::+    Ptr GValue -> IO CUInt++set_flags :: GValue -> CUInt -> IO ()+set_flags gv f = withManagedPtr gv $ flip _set_flags f++get_flags :: GValue -> IO CUInt+get_flags gv = withManagedPtr gv _get_flags
+ Data/GI/Base/GVariant.hsc view
@@ -0,0 +1,977 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE EmptyDataDecls #-}+{-|+This module contains some helper functions for dealing with GVariant+values. The simplest way of dealing with them is by using the+'IsGVariant' typeclass:++> str <- fromGVariant variant :: IO (Maybe Text)++assuming that the variant is expected to contain a+string in UTF8 encoding. The code becomes even shorter if the type+checker can determine the return type for you:+++> readStringVariant :: GVariant -> IO Text+> readStringVariant variant =+>   fromGVariant variant >>= \case+>      Nothing  -> error "Variant was not a string"+>      Just str -> return str++Alternatively, you can use manually the gvariantFrom* and+gvariantTo* family of functions.+-}+module Data.GI.Base.GVariant+    ( IsGVariant(..)+    , IsGVariantBasicType++    , noGVariant++    , gvariantGetTypeString++    -- * Type wrappers+    -- | Some 'GVariant' types are isomorphic to Haskell types, but they+    -- carry some extra information. For example, there is a tuple+    -- singlet type, which is isomorphic to a single Haskell value+    -- with the added bit of information that it is wrapped in a tuple+    -- container. In order to use these values you can use the+    -- following wrappers, which allow the 'IsGVariant' instance to+    -- disambiguate the requested type properly.++    , GVariantSinglet(GVariantSinglet)+    , GVariantDictEntry(GVariantDictEntry)+    , GVariantHandle(GVariantHandle)+    , GVariantObjectPath+    , newGVariantObjectPath+    , gvariantObjectPathToText+    , GVariantSignature+    , newGVariantSignature+    , gvariantSignatureToText++    -- * Manual memory management++    , wrapGVariantPtr+    , newGVariantFromPtr+    , unrefGVariant+    , disownGVariant++    -- * Manual conversions++    -- ** Basic types+    --+    -- | The use of these should be fairly self-explanatory. If you+    -- want to convert a Haskell type into a 'GVariant', use+    -- gvariantTo*. If you want to convert a 'GVariant' into a Haskell+    -- type, use gvariantFrom*. The conversion can fail if the+    -- 'GVariant' is not of the expected type (if you want to convert+    -- a 'GVariant' containing a 'Int16' into a 'Text' value, say), in+    -- which case 'Nothing' will be returned.+    , gvariantToBool+    , gvariantFromBool++    , gvariantToWord8+    , gvariantFromWord8++    , gvariantToInt16+    , gvariantFromInt16++    , gvariantToWord16+    , gvariantFromWord16++    , gvariantToInt32+    , gvariantFromInt32++    , gvariantToWord32+    , gvariantFromWord32++    , gvariantToInt64+    , gvariantFromInt64++    , gvariantToWord64+    , gvariantFromWord64++    , gvariantToHandle+    , gvariantFromHandle++    , gvariantToDouble+    , gvariantFromDouble++    , gvariantToText+    , gvariantFromText++    , gvariantToObjectPath+    , gvariantFromObjectPath++    , gvariantToSignature+    , gvariantFromSignature++    -- ** Container type conversions+    , gvariantToGVariant+    , gvariantFromGVariant++    , gvariantToBytestring+    , gvariantFromBytestring++    , gvariantFromMaybe+    , gvariantToMaybe++    , gvariantFromDictEntry+    , gvariantToDictEntry++    , gvariantFromMap+    , gvariantToMap++    , gvariantFromList+    , gvariantToList++    , gvariantFromTuple+    , gvariantToTuple+    ) where++#include <glib-object.h>++#if !MIN_VERSION_base(4,8,0)+import Control.Applicative ((<$>), (<*>))+#endif+import Control.Monad (when, void, (>=>))+import Control.Exception.Base (bracket)++import Data.Text (Text)+import Data.ByteString (ByteString)+import qualified Data.ByteString as B+import Data.Word+import Data.Int+import Data.Monoid ((<>))+import Data.Maybe (isJust, fromJust)+import qualified Data.Map as M++import System.IO.Unsafe (unsafePerformIO)+import Foreign.C+import Foreign.Ptr++import Data.GI.Base.BasicTypes (GVariant(..))+import Data.GI.Base.BasicConversions+import Data.GI.Base.ManagedPtr (withManagedPtr, withManagedPtrList,+                                newManagedPtr', disownManagedPtr)+import Data.GI.Base.Utils (freeMem)++-- | An alias for @Nothing :: Maybe GVariant@ to save some typing.+noGVariant :: Maybe GVariant+noGVariant = Nothing++-- | The typeclass for types that can be automatically marshalled into+-- 'GVariant' using 'toGVariant' and 'fromGVariant'.+class IsGVariant a where+    -- | Convert a value of the given type into a GVariant.+    toGVariant   :: a -> IO GVariant+    -- | Try to decode a 'GVariant' into a target type. If the+    -- conversion fails we return 'Nothing'. The type that was+    -- expected can be obtained by calling 'toGVariantFormatString',+    -- and the actual type as understood by the 'GVariant' code can be+    -- obtained by calling 'gvariantToTypeString'.+    fromGVariant :: GVariant -> IO (Maybe a)+    -- | The expected format string for this type (the argument is+    -- ignored).+    toGVariantFormatString :: a -> Text++-- Same as fromGVariant, for cases where we have checked that things+-- have the right type in advance.+unsafeFromGVariant :: IsGVariant a => GVariant -> IO a+unsafeFromGVariant gv =+    fromGVariant gv >>= \case+                 Nothing -> error "Error decoding GVariant. This is a bug in haskell-gi, please report it."+                 Just value -> return value++-- | The typeclass for basic type 'GVariant' types, i.e. those that+-- are not containers.+class Ord a => IsGVariantBasicType a++-- | Haskell has no notion of one element tuples, but GVariants do, so+-- the following allows for marshalling one element tuples properly+-- using 'fromGVariant' and 'toGVariant'. For instance, to construct a+-- single element tuple containing a string, you could do+--+-- > toGVariant (GVariantSinglet "Test")+newtype GVariantSinglet a = GVariantSinglet a+    deriving (Eq, Show)++data GVariantType++foreign import ccall "g_variant_type_new" g_variant_type_new ::+    CString -> IO (Ptr GVariantType)++foreign import ccall "g_variant_type_free" g_variant_type_free ::+    Ptr GVariantType -> IO ()++foreign import ccall "g_variant_is_of_type" g_variant_is_of_type ::+    Ptr GVariant -> Ptr GVariantType -> IO #{type gboolean}++withGVariantType :: Text -> (Ptr GVariantType -> IO a) -> IO a+withGVariantType text action = withTextCString text $ \textPtr ->+                               bracket (g_variant_type_new textPtr)+                                       g_variant_type_free+                                       action++gvariantIsOfType :: Text -> GVariant -> IO Bool+gvariantIsOfType typeString variant =+    withGVariantType typeString $+        \typePtr ->+            (toEnum . fromIntegral) <$> withManagedPtr variant+                                        (\vptr -> g_variant_is_of_type+                                                  vptr typePtr)++withExplicitType :: Text -> (Ptr GVariant -> IO a) -> GVariant -> IO (Maybe a)+withExplicitType format action variant = do+  check <- gvariantIsOfType format variant+  if check+  then Just <$> withManagedPtr variant action+  else return Nothing++withTypeCheck :: forall a. (IsGVariant a) =>+                 (Ptr GVariant -> IO a) -> GVariant -> IO (Maybe a)+withTypeCheck = withExplicitType $ toGVariantFormatString (undefined :: a)++foreign import ccall "g_variant_get_type_string" g_variant_get_type_string+    :: Ptr GVariant -> IO CString++-- | Get the expected type of a 'GVariant', in 'GVariant'+-- notation. See+-- <https://developer.gnome.org/glib/stable/glib-GVariantType.html>+-- for the meaning of the resulting format string.+gvariantGetTypeString :: GVariant -> IO Text+gvariantGetTypeString variant =+    withManagedPtr variant (g_variant_get_type_string >=> cstringToText)++foreign import ccall "g_variant_is_floating" g_variant_is_floating ::+    Ptr GVariant -> IO CInt+foreign import ccall "g_variant_ref_sink" g_variant_ref_sink ::+    Ptr GVariant -> IO (Ptr GVariant)+foreign import ccall "g_variant_ref" g_variant_ref ::+    Ptr GVariant -> IO (Ptr GVariant)+foreign import ccall "g_variant_unref" g_variant_unref ::+    Ptr GVariant -> IO ()+foreign import ccall "&g_variant_unref" ptr_to_g_variant_unref ::+    FunPtr (Ptr GVariant -> IO ())++-- | Take ownership of a passed in 'Ptr' (typically created just for+-- us, so if it is floating we sink it).+wrapGVariantPtr :: Ptr GVariant -> IO GVariant+wrapGVariantPtr ptr = do+  floating <- g_variant_is_floating ptr+  when (floating /= 0) $ void $ g_variant_ref_sink ptr+  fPtr <- newManagedPtr' ptr_to_g_variant_unref ptr+  return $! GVariant fPtr++-- | Construct a Haskell wrapper for the given 'GVariant', without+-- assuming ownership.+newGVariantFromPtr :: Ptr GVariant -> IO GVariant+newGVariantFromPtr ptr = do+  fPtr <- g_variant_ref ptr >>= newManagedPtr' ptr_to_g_variant_unref+  return $! GVariant fPtr++-- | Remove a reference to the given 'GVariant'.+unrefGVariant :: GVariant -> IO ()+unrefGVariant gv = withManagedPtr gv g_variant_unref++-- | Disown a `GVariant`, i.e. do not unref the underlying object when+-- the Haskell object is garbage collected.+disownGVariant :: GVariant -> IO (Ptr GVariant)+disownGVariant = disownManagedPtr++instance IsGVariant Bool where+    toGVariant = gvariantFromBool+    fromGVariant = gvariantToBool+    toGVariantFormatString _ = "b"+instance IsGVariantBasicType Bool++foreign import ccall "g_variant_new_boolean" new_bool+    :: #{type gboolean} -> IO (Ptr GVariant)++gvariantFromBool :: Bool -> IO GVariant+gvariantFromBool = (new_bool . fromIntegral . fromEnum) >=> wrapGVariantPtr++foreign import ccall "g_variant_get_boolean" get_bool+    :: Ptr GVariant -> IO #{type gboolean}++gvariantToBool :: GVariant -> IO (Maybe Bool)+gvariantToBool = withTypeCheck $ get_bool >=> (return . toEnum . fromIntegral)++instance IsGVariant Word8 where+    toGVariant = gvariantFromWord8+    fromGVariant = gvariantToWord8+    toGVariantFormatString _ = "y"+instance IsGVariantBasicType Word8++foreign import ccall "g_variant_new_byte" new_byte+    :: #{type guchar} -> IO (Ptr GVariant)++gvariantFromWord8 :: Word8 -> IO GVariant+gvariantFromWord8 = (new_byte . fromIntegral) >=> wrapGVariantPtr++foreign import ccall "g_variant_get_byte" get_byte+    :: Ptr GVariant -> IO #{type guchar}++gvariantToWord8 :: GVariant -> IO (Maybe Word8)+gvariantToWord8 = withTypeCheck $ get_byte >=> (return . fromIntegral)++instance IsGVariant Int16 where+    toGVariant = gvariantFromInt16+    fromGVariant = gvariantToInt16+    toGVariantFormatString _ = "n"+instance IsGVariantBasicType Int16++foreign import ccall "g_variant_new_int16" new_int16+    :: #{type gint16} -> IO (Ptr GVariant)++gvariantFromInt16 :: Int16 -> IO GVariant+gvariantFromInt16 = (new_int16 . fromIntegral) >=> wrapGVariantPtr++foreign import ccall "g_variant_get_int16" get_int16+    :: Ptr GVariant -> IO #{type gint16}++gvariantToInt16 :: GVariant -> IO (Maybe Int16)+gvariantToInt16 = withTypeCheck $ get_int16 >=> (return . fromIntegral)++instance IsGVariant Word16 where+    toGVariant = gvariantFromWord16+    fromGVariant = gvariantToWord16+    toGVariantFormatString _ = "q"+instance IsGVariantBasicType Word16++foreign import ccall "g_variant_new_uint16" new_uint16+    :: #{type guint16} -> IO (Ptr GVariant)++gvariantFromWord16 :: Word16 -> IO GVariant+gvariantFromWord16 = new_uint16 . fromIntegral >=> wrapGVariantPtr++foreign import ccall "g_variant_get_uint16" get_uint16+    :: Ptr GVariant -> IO #{type guint16}++gvariantToWord16 :: GVariant -> IO (Maybe Word16)+gvariantToWord16 = withTypeCheck $ get_uint16 >=> (return . fromIntegral)++instance IsGVariant Int32 where+    toGVariant = gvariantFromInt32+    fromGVariant = gvariantToInt32+    toGVariantFormatString _ = "i"+instance IsGVariantBasicType Int32++foreign import ccall "g_variant_new_int32" new_int32+    :: #{type gint16} -> IO (Ptr GVariant)++gvariantFromInt32 :: Int32 -> IO GVariant+gvariantFromInt32 = (new_int32 . fromIntegral) >=> wrapGVariantPtr++foreign import ccall "g_variant_get_int32" get_int32+    :: Ptr GVariant -> IO #{type gint32}++gvariantToInt32 :: GVariant -> IO (Maybe Int32)+gvariantToInt32 = withTypeCheck $ get_int32 >=> (return . fromIntegral)++instance IsGVariant Word32 where+    toGVariant = gvariantFromWord32+    fromGVariant = gvariantToWord32+    toGVariantFormatString _ = "u"+instance IsGVariantBasicType Word32++foreign import ccall "g_variant_new_uint32" new_uint32+    :: #{type guint32} -> IO (Ptr GVariant)++gvariantFromWord32 :: Word32 -> IO GVariant+gvariantFromWord32 = (new_uint32 . fromIntegral) >=> wrapGVariantPtr++foreign import ccall "g_variant_get_uint32" get_uint32+    :: Ptr GVariant -> IO #{type guint32}++gvariantToWord32 :: GVariant -> IO (Maybe Word32)+gvariantToWord32 = withTypeCheck $ get_uint32 >=> (return . fromIntegral)++instance IsGVariant Int64 where+    toGVariant = gvariantFromInt64+    fromGVariant = gvariantToInt64+    toGVariantFormatString _ = "x"+instance IsGVariantBasicType Int64++foreign import ccall "g_variant_new_int64" new_int64+    :: #{type gint64} -> IO (Ptr GVariant)++gvariantFromInt64 :: Int64 -> IO GVariant+gvariantFromInt64 = (new_int64 . fromIntegral) >=> wrapGVariantPtr++foreign import ccall "g_variant_get_int64" get_int64+    :: Ptr GVariant -> IO #{type gint64}++gvariantToInt64 :: GVariant -> IO (Maybe Int64)+gvariantToInt64 = withTypeCheck $ get_int64 >=> (return . fromIntegral)++instance IsGVariant Word64 where+    toGVariant = gvariantFromWord64+    fromGVariant = gvariantToWord64+    toGVariantFormatString _ = "t"+instance IsGVariantBasicType Word64++foreign import ccall "g_variant_new_uint64" new_uint64+    :: #{type guint64} -> IO (Ptr GVariant)++gvariantFromWord64 :: Word64 -> IO GVariant+gvariantFromWord64 = (new_uint64 . fromIntegral) >=> wrapGVariantPtr++foreign import ccall "g_variant_get_uint64" get_uint64+    :: Ptr GVariant -> IO #{type guint64}++gvariantToWord64 :: GVariant -> IO (Maybe Word64)+gvariantToWord64 = withTypeCheck $ get_uint64 >=> (return . fromIntegral)++newtype GVariantHandle = GVariantHandle Int32+    deriving (Eq, Ord, Show)++instance IsGVariant GVariantHandle where+    toGVariant (GVariantHandle h) = gvariantFromHandle h+    fromGVariant = gvariantToHandle >=> (return . (GVariantHandle <$>))+    toGVariantFormatString _ = "h"+instance IsGVariantBasicType GVariantHandle++foreign import ccall "g_variant_new_handle" new_handle+    :: #{type gint32} -> IO (Ptr GVariant)++-- | Convert a DBus handle (an 'Int32') into a 'GVariant'.+gvariantFromHandle :: Int32 -> IO GVariant+gvariantFromHandle h = (new_handle . fromIntegral) h >>= wrapGVariantPtr++foreign import ccall "g_variant_get_handle" get_handle+    :: Ptr GVariant -> IO #{type gint32}++-- | Extract the DBus handle (an 'Int32') inside a 'GVariant'.+gvariantToHandle :: GVariant -> IO (Maybe Int32)+gvariantToHandle =+  withExplicitType (toGVariantFormatString (undefined :: GVariantHandle)) $+                   get_handle >=> (return . fromIntegral)++instance IsGVariant Double where+    toGVariant = gvariantFromDouble+    fromGVariant = gvariantToDouble+    toGVariantFormatString _ = "d"+instance IsGVariantBasicType Double++foreign import ccall "g_variant_new_double" new_double+    :: #{type gdouble} -> IO (Ptr GVariant)++gvariantFromDouble :: Double -> IO GVariant+gvariantFromDouble = (new_double . realToFrac) >=> wrapGVariantPtr++foreign import ccall "g_variant_get_double" get_double+    :: Ptr GVariant -> IO #{type gdouble}++gvariantToDouble :: GVariant -> IO (Maybe Double)+gvariantToDouble = withTypeCheck $ get_double >=> (return . realToFrac)++instance IsGVariant Text where+    toGVariant = gvariantFromText+    fromGVariant = gvariantToText+    toGVariantFormatString _ = "s"+instance IsGVariantBasicType Text++foreign import ccall "g_variant_get_string" _get_string+    :: Ptr GVariant -> Ptr #{type gsize} -> IO CString++get_string :: Ptr GVariant -> IO CString+get_string v = _get_string v nullPtr++-- | Decode an UTF-8 encoded string 'GVariant' into 'Text'.+gvariantToText :: GVariant -> IO (Maybe Text)+gvariantToText = withTypeCheck $ get_string >=> cstringToText++foreign import ccall "g_variant_new_take_string" take_string+    :: CString -> IO (Ptr GVariant)++-- | Encode a 'Text' into an UTF-8 encoded string 'GVariant'.+gvariantFromText :: Text -> IO GVariant+gvariantFromText = textToCString >=> take_string >=> wrapGVariantPtr++foreign import ccall "g_variant_is_object_path" g_variant_is_object_path ::+    CString -> IO #{type gboolean}++-- | An object representing a DBus object path, which is a particular+-- type of 'GVariant' too. (Just a string with some specific+-- requirements.) In order to construct/deconstruct a+-- 'GVariantObjectPath' one can use 'newGVariantObjectPath'+-- and 'gvariantObjectPathToText'.+newtype GVariantObjectPath = GVariantObjectPath Text+    deriving (Ord, Eq, Show)++-- | Try to construct a DBus object path. If the passed string is not+-- a valid object path 'Nothing' will be returned.+newGVariantObjectPath :: Text -> Maybe GVariantObjectPath+newGVariantObjectPath p = unsafePerformIO $+   withTextCString p $ \cstr -> do+     isObjectPath <- toEnum . fromIntegral <$> g_variant_is_object_path cstr+     if isObjectPath+     then return $ Just (GVariantObjectPath p)+     else return Nothing++-- | Return the 'Text' representation of a 'GVariantObjectPath'.+gvariantObjectPathToText :: GVariantObjectPath -> Text+gvariantObjectPathToText (GVariantObjectPath p) = p++instance IsGVariant GVariantObjectPath where+    toGVariant = gvariantFromObjectPath+    fromGVariant = gvariantToObjectPath >=> return . (GVariantObjectPath <$>)+    toGVariantFormatString _ = "o"+instance IsGVariantBasicType GVariantObjectPath++foreign import ccall "g_variant_new_object_path" new_object_path+    :: CString -> IO (Ptr GVariant)++-- | Construct a 'GVariant' containing an object path. In order to+-- build a 'GVariantObjectPath' value see 'newGVariantObjectPath'.+gvariantFromObjectPath :: GVariantObjectPath -> IO GVariant+gvariantFromObjectPath (GVariantObjectPath p) =+    withTextCString p $ new_object_path >=> wrapGVariantPtr++-- | Extract a 'GVariantObjectPath' from a 'GVariant', represented as+-- its underlying 'Text' representation.+gvariantToObjectPath :: GVariant -> IO (Maybe Text)+gvariantToObjectPath =+    withExplicitType (toGVariantFormatString (undefined :: GVariantObjectPath))+                         (get_string >=> cstringToText)++foreign import ccall "g_variant_is_signature" g_variant_is_signature ::+    CString -> IO #{type gboolean}++-- | An object representing a DBus signature, which is a particular+-- type of 'GVariant' too. (Just a string with some specific+-- requirements.) In order to construct/deconstruct a+-- 'GVariantSignature' one can use 'newGVariantSignature' and+-- 'gvariantSignatureToText'.+newtype GVariantSignature = GVariantSignature Text+    deriving (Ord, Eq, Show)++-- | Try to construct a DBus object path. If the passed string is not+-- a valid DBus signature 'Nothing' will be returned.+newGVariantSignature :: Text -> Maybe GVariantSignature+newGVariantSignature p = unsafePerformIO $+   withTextCString p $ \cstr -> do+     isSignature <- toEnum . fromIntegral <$> g_variant_is_signature cstr+     if isSignature+     then return $ Just (GVariantSignature p)+     else return Nothing++-- | Return the 'Text' representation of a 'GVariantSignature'.+gvariantSignatureToText :: GVariantSignature -> Text+gvariantSignatureToText (GVariantSignature p) = p++instance IsGVariant GVariantSignature where+    toGVariant = gvariantFromSignature+    fromGVariant = gvariantToSignature >=> return . (GVariantSignature <$>)+    toGVariantFormatString _ = "g"+instance IsGVariantBasicType GVariantSignature++foreign import ccall "g_variant_new_signature" new_signature+    :: CString -> IO (Ptr GVariant)++-- | Construct a 'GVariant' containing an DBus signature. In order to+-- build a 'GVariantSignature' value see 'newGVariantSignature'.+gvariantFromSignature :: GVariantSignature -> IO GVariant+gvariantFromSignature (GVariantSignature p) =+    withTextCString p $ new_signature >=> wrapGVariantPtr++-- | Extract a 'GVariantSignature' from a 'GVariant', represented as+-- 'Text'.+gvariantToSignature :: GVariant -> IO (Maybe Text)+gvariantToSignature =+    withExplicitType (toGVariantFormatString (undefined :: GVariantSignature))+                         $ get_string >=> cstringToText++instance IsGVariant GVariant where+    toGVariant = gvariantFromGVariant+    fromGVariant = gvariantToGVariant+    toGVariantFormatString _ = "v"++foreign import ccall "g_variant_new_variant" new_variant+    :: Ptr GVariant -> IO (Ptr GVariant)++-- | Box a 'GVariant' inside another 'GVariant'.+gvariantFromGVariant :: GVariant -> IO GVariant+gvariantFromGVariant v = withManagedPtr v $ new_variant >=> wrapGVariantPtr++foreign import ccall "g_variant_get_variant" get_variant+    :: Ptr GVariant -> IO (Ptr GVariant)++-- | Unbox a 'GVariant' contained inside another 'GVariant'.+gvariantToGVariant :: GVariant -> IO (Maybe GVariant)+gvariantToGVariant = withTypeCheck $ get_variant >=> wrapGVariantPtr++instance IsGVariant ByteString where+    toGVariant = gvariantFromBytestring+    fromGVariant = gvariantToBytestring+    toGVariantFormatString _ = "ay"++foreign import ccall "g_variant_get_bytestring" get_bytestring+    :: Ptr GVariant -> IO CString++-- | Extract a zero terminated list of bytes into a 'ByteString'.+gvariantToBytestring :: GVariant -> IO (Maybe ByteString)+gvariantToBytestring = withTypeCheck (get_bytestring >=> cstringToByteString)++foreign import ccall "g_variant_new_bytestring" new_bytestring+    :: CString -> IO (Ptr GVariant)++-- | Encode a 'ByteString' into a list of bytes 'GVariant'.+gvariantFromBytestring :: ByteString -> IO GVariant+gvariantFromBytestring bs = wrapGVariantPtr =<<+                              B.useAsCString bs new_bytestring+++foreign import ccall "g_variant_n_children" g_variant_n_children+    :: Ptr GVariant -> IO #{type gsize}++foreign import ccall "g_variant_get_child_value" g_variant_get_child_value+    :: Ptr GVariant -> #{type gsize} -> IO (Ptr GVariant)++-- No type checking is done here, it is assumed that the caller knows+-- that the passed variant is indeed of a container type.+gvariant_get_children :: (Ptr GVariant) -> IO [GVariant]+gvariant_get_children vptr = do+      n_children <- g_variant_n_children vptr+      mapM ((g_variant_get_child_value vptr) >=> wrapGVariantPtr)+               [0..(n_children-1)]++instance IsGVariant a => IsGVariant (Maybe a) where+    toGVariant   = gvariantFromMaybe+    fromGVariant = gvariantToMaybe+    toGVariantFormatString _ = "m" <> toGVariantFormatString (undefined :: a)++foreign import ccall "g_variant_new_maybe" g_variant_new_maybe ::+    Ptr GVariantType -> Ptr GVariant -> IO (Ptr GVariant)++-- | Convert a 'Maybe' value into a corresponding 'GVariant' of maybe+-- type.+gvariantFromMaybe :: forall a. IsGVariant a => Maybe a -> IO GVariant+gvariantFromMaybe m = do+  let fmt = toGVariantFormatString (undefined :: a)+  withGVariantType fmt $ \tPtr ->+      case m of+        Just child -> do+               childVariant <- toGVariant child+               withManagedPtr childVariant+                      (g_variant_new_maybe tPtr >=> wrapGVariantPtr)+        Nothing -> g_variant_new_maybe tPtr nullPtr >>= wrapGVariantPtr++-- | Try to decode a maybe 'GVariant' into the corresponding 'Maybe'+-- type. If the conversion is successful this returns @Just x@, where+-- @x@ itself is of 'Maybe' type. So, in particular, @Just Nothing@+-- indicates a successful call, and means that the GVariant of maybe+-- type was empty.+gvariantToMaybe :: forall a. IsGVariant a => GVariant -> IO (Maybe (Maybe a))+gvariantToMaybe v = do+  let fmt = toGVariantFormatString (undefined :: Maybe a)+  withExplicitType fmt gvariant_get_children v >>=+   \case+     Just [] -> return (Just Nothing)+     Just [child] -> fromGVariant child >>=+                     \case+                       Nothing -> return Nothing+                       Just result -> return (Just (Just result))+     Just _ -> error "gvariantToMaybe :: the impossible happened, this is a bug."+     Nothing -> return Nothing++-- | A DictEntry 'GVariant' is isomorphic to a two-tuple. Wrapping the+-- values into a 'GVariantDictentry' allows the 'IsGVariant' instance+-- to do the right thing.+data GVariantDictEntry key value = GVariantDictEntry key value+                                   deriving (Eq, Show)++instance (IsGVariant a, IsGVariantBasicType a, IsGVariant b) =>+    IsGVariant (GVariantDictEntry a b) where+        toGVariant (GVariantDictEntry key value) =+            gvariantFromDictEntry key value+        fromGVariant gv =+            ((uncurry GVariantDictEntry) <$>) <$> gvariantToDictEntry gv+        toGVariantFormatString _ = "{"+                                   <> toGVariantFormatString (undefined :: a)+                                   <> toGVariantFormatString (undefined :: b)+                                   <> "}"++foreign import ccall "g_variant_new_dict_entry" g_variant_new_dict_entry ::+    Ptr GVariant -> Ptr GVariant -> IO (Ptr GVariant)++-- | Construct a 'GVariant' of type DictEntry from the given 'key' and+-- 'value'. The key must be a basic 'GVariant' type, i.e. not a+-- container. This is determined by whether it belongs to the+-- 'IsGVariantBasicType' typeclass. On the other hand 'value' is an+-- arbitrary 'GVariant', and in particular it can be a container type.+gvariantFromDictEntry :: (IsGVariant key, IsGVariantBasicType key,+                          IsGVariant value) =>+                         key -> value -> IO GVariant+gvariantFromDictEntry key value = do+  keyVar <- toGVariant key+  valueVar <- toGVariant value+  withManagedPtr keyVar $ \keyPtr ->+      withManagedPtr valueVar $ \valuePtr ->+          g_variant_new_dict_entry keyPtr valuePtr >>= wrapGVariantPtr++-- | Unpack a DictEntry variant into 'key' and 'value', which are+-- returned as a two element tuple in case of success.+gvariantToDictEntry :: forall key value.+                       (IsGVariant key, IsGVariantBasicType key,+                        IsGVariant value) =>+                       GVariant -> IO (Maybe (key, value))+gvariantToDictEntry =+    withExplicitType fmt $ \varPtr -> do+      [key, value] <- gvariant_get_children varPtr+      (,) <$> unsafeFromGVariant key <*> unsafeFromGVariant value+    where+      fmt = toGVariantFormatString (undefined :: GVariantDictEntry key value)++instance (IsGVariant a, IsGVariantBasicType a, IsGVariant b) =>+    IsGVariant (M.Map a b) where+        toGVariant = gvariantFromMap+        fromGVariant = gvariantToMap+        toGVariantFormatString _ = "a{"+                                   <> toGVariantFormatString (undefined :: a)+                                   <> toGVariantFormatString (undefined :: b)+                                   <> "}"++-- | Pack a 'Map' into a 'GVariant' for dictionary type, which is just+-- an array of 'GVariantDictEntry'.+gvariantFromMap :: (IsGVariant key, IsGVariantBasicType key,+                    IsGVariant value) =>+                   M.Map key value -> IO GVariant+gvariantFromMap m = gvariantFromList $+                       map (uncurry GVariantDictEntry) (M.toList m)++-- | Unpack a 'GVariant' into a 'M.Map'. Notice that this assumes that+-- all the elements in the 'GVariant' array of 'GVariantDictEntry' are+-- of the same type, which is not necessary for a generic 'GVariant',+-- so this is somewhat restrictive. For the general case it is+-- necessary to use 'gvariantToList' plus 'gvariantToDictEntry'+-- directly.+gvariantToMap :: forall key value.+                 (IsGVariant key, IsGVariantBasicType key,+                  IsGVariant value) =>+                 GVariant -> IO (Maybe (M.Map key value))+gvariantToMap = gvariantToList >=> (return . (fromDictEntryList <$>))+    where fromDictEntryList :: [GVariantDictEntry key value] ->+                               M.Map key value+          fromDictEntryList = M.fromList . (map tuplefy)+          tuplefy :: GVariantDictEntry key value -> (key, value)+          tuplefy (GVariantDictEntry key value) = (key, value)++instance IsGVariant a => IsGVariant [a] where+    toGVariant   = gvariantFromList+    fromGVariant = gvariantToList+    toGVariantFormatString _ = "a" <> toGVariantFormatString (undefined :: a)++foreign import ccall "g_variant_new_array" g_variant_new_array ::+    Ptr GVariantType -> Ptr (Ptr GVariant) -> #{type gsize} -> IO (Ptr GVariant)++-- | Given a list of elements construct a 'GVariant' array containing+-- them.+gvariantFromList :: forall a. IsGVariant a => [a] -> IO GVariant+gvariantFromList children = do+  let fmt = toGVariantFormatString (undefined :: a)+  mapM toGVariant children >>= \childVariants ->+      withManagedPtrList childVariants $ \childrenPtrs -> do+          withGVariantType fmt $ \childType -> do+             packed <- packPtrArray childrenPtrs+             result <- g_variant_new_array childType packed+                            (fromIntegral $ length children)+             freeMem packed+             wrapGVariantPtr result++-- | Unpack a 'GVariant' array into its elements.+gvariantToList :: forall a. IsGVariant a => GVariant -> IO (Maybe [a])+gvariantToList = withExplicitType (toGVariantFormatString (undefined :: [a]))+                 (gvariant_get_children >=> mapM unsafeFromGVariant)++foreign import ccall "g_variant_new_tuple" g_variant_new_tuple+        :: Ptr (Ptr GVariant) -> #{type gsize} -> IO (Ptr GVariant)++-- | Given a list of 'GVariant', construct a 'GVariant' tuple+-- containing the elements in the list.+gvariantFromTuple :: [GVariant] -> IO GVariant+gvariantFromTuple children =+    withManagedPtrList children $ \childrenPtrs -> do+      packed <- packPtrArray childrenPtrs+      result <- g_variant_new_tuple packed (fromIntegral $ length children)+      freeMem packed+      wrapGVariantPtr result++-- | Extract the children of a 'GVariant' tuple into a list.+gvariantToTuple :: GVariant -> IO (Maybe [GVariant])+gvariantToTuple = withExplicitType "r" gvariant_get_children++-- | The empty tuple GVariant, mostly useful for type checking.+instance IsGVariant () where+    toGVariant _ = gvariantFromTuple []+    fromGVariant = withTypeCheck (const $ return ())+    toGVariantFormatString _ = "()"++-- | One element tuples.+instance IsGVariant a => IsGVariant (GVariantSinglet a) where+    toGVariant (GVariantSinglet s) = gvariantFromSinglet s+    fromGVariant = gvariantToSinglet >=> return . (GVariantSinglet <$>)+    toGVariantFormatString _ = "("+                               <> toGVariantFormatString (undefined :: a)+                               <> ")"++gvariantFromSinglet :: IsGVariant a => a -> IO GVariant+gvariantFromSinglet s = do+  sv <- toGVariant s+  gvariantFromTuple [sv]++gvariantToSinglet :: forall a. IsGVariant a => GVariant -> IO (Maybe a)+gvariantToSinglet = withExplicitType fmt+                    (gvariant_get_children+                     >=> return . head+                     >=> unsafeFromGVariant)+    where fmt = toGVariantFormatString (undefined :: GVariantSinglet a)++instance (IsGVariant a, IsGVariant b) => IsGVariant (a,b) where+    toGVariant = gvariantFromTwoTuple+    fromGVariant = gvariantToTwoTuple+    toGVariantFormatString _ = "("+                               <> toGVariantFormatString (undefined :: a)+                               <> toGVariantFormatString (undefined :: b)+                               <> ")"++gvariantFromTwoTuple :: (IsGVariant a, IsGVariant b) =>+                        (a,b) -> IO GVariant+gvariantFromTwoTuple (a, b) = do+  va <- toGVariant a+  vb <- toGVariant b+  gvariantFromTuple [va, vb]++gvariantToTwoTuple :: forall a b. (IsGVariant a, IsGVariant b) =>+                      GVariant -> IO (Maybe (a,b))+gvariantToTwoTuple variant = do+  let expectedType = toGVariantFormatString (undefined :: (a,b))+  maybeChildren <- withExplicitType expectedType gvariant_get_children variant+  if isJust maybeChildren+  then do+    let (Just [a1,a2]) = maybeChildren+    (ma1, ma2) <- (,) <$> fromGVariant a1 <*> fromGVariant a2+    return $ if isJust ma1 && isJust ma2+             then Just (fromJust ma1, fromJust ma2)+             else Nothing+  else return Nothing++instance (IsGVariant a, IsGVariant b, IsGVariant c) => IsGVariant (a,b,c) where+    toGVariant = gvariantFromThreeTuple+    fromGVariant = gvariantToThreeTuple+    toGVariantFormatString _ = "("+                               <> toGVariantFormatString (undefined :: a)+                               <> toGVariantFormatString (undefined :: b)+                               <> toGVariantFormatString (undefined :: c)+                               <> ")"++gvariantFromThreeTuple :: (IsGVariant a, IsGVariant b, IsGVariant c) =>+                        (a,b,c) -> IO GVariant+gvariantFromThreeTuple (a, b, c) = do+  va <- toGVariant a+  vb <- toGVariant b+  vc <- toGVariant c+  gvariantFromTuple [va, vb, vc]++gvariantToThreeTuple :: forall a b c. (IsGVariant a, IsGVariant b,+                                                  IsGVariant c) =>+                      GVariant -> IO (Maybe (a,b,c))+gvariantToThreeTuple variant = do+  let expectedType = toGVariantFormatString (undefined :: (a,b,c))+  maybeChildren <- withExplicitType expectedType gvariant_get_children variant+  if isJust maybeChildren+  then do+    let (Just [a1,a2,a3]) = maybeChildren+    (ma1, ma2, ma3) <- (,,) <$> fromGVariant a1+                            <*> fromGVariant a2+                            <*> fromGVariant a3+    return $ if isJust ma1 && isJust ma2 && isJust ma3+             then Just (fromJust ma1, fromJust ma2, fromJust ma3)+             else Nothing+  else return Nothing++instance (IsGVariant a, IsGVariant b, IsGVariant c, IsGVariant d) =>+    IsGVariant (a,b,c,d) where+    toGVariant = gvariantFromFourTuple+    fromGVariant = gvariantToFourTuple+    toGVariantFormatString _ = "("+                               <> toGVariantFormatString (undefined :: a)+                               <> toGVariantFormatString (undefined :: b)+                               <> toGVariantFormatString (undefined :: c)+                               <> toGVariantFormatString (undefined :: d)+                               <> ")"++gvariantFromFourTuple :: (IsGVariant a, IsGVariant b, IsGVariant c,+                          IsGVariant d) => (a,b,c,d) -> IO GVariant+gvariantFromFourTuple (a, b, c, d) = do+  va <- toGVariant a+  vb <- toGVariant b+  vc <- toGVariant c+  vd <- toGVariant d+  gvariantFromTuple [va, vb, vc, vd]++gvariantToFourTuple :: forall a b c d. (IsGVariant a, IsGVariant b,+                                        IsGVariant c, IsGVariant d) =>+                      GVariant -> IO (Maybe (a,b,c,d))+gvariantToFourTuple variant = do+  let expectedType = toGVariantFormatString (undefined :: (a,b,c,d))+  maybeChildren <- withExplicitType expectedType gvariant_get_children variant+  if isJust maybeChildren+  then do+    let (Just [a1,a2,a3,a4]) = maybeChildren+    (ma1, ma2, ma3,ma4) <- (,,,) <$> fromGVariant a1+                                 <*> fromGVariant a2+                                 <*> fromGVariant a3+                                 <*> fromGVariant a4+    return $ if isJust ma1 && isJust ma2 && isJust ma3 && isJust ma4+             then Just (fromJust ma1, fromJust ma2, fromJust ma3, fromJust ma4)+             else Nothing+  else return Nothing++instance (IsGVariant a, IsGVariant b, IsGVariant c, IsGVariant d, IsGVariant e)+    => IsGVariant (a,b,c,d,e) where+    toGVariant = gvariantFromFiveTuple+    fromGVariant = gvariantToFiveTuple+    toGVariantFormatString _ = "("+                               <> toGVariantFormatString (undefined :: a)+                               <> toGVariantFormatString (undefined :: b)+                               <> toGVariantFormatString (undefined :: c)+                               <> toGVariantFormatString (undefined :: d)+                               <> toGVariantFormatString (undefined :: e)+                               <> ")"++gvariantFromFiveTuple :: (IsGVariant a, IsGVariant b, IsGVariant c,+                          IsGVariant d, IsGVariant e) =>+                         (a,b,c,d,e) -> IO GVariant+gvariantFromFiveTuple (a, b, c, d, e) = do+  va <- toGVariant a+  vb <- toGVariant b+  vc <- toGVariant c+  vd <- toGVariant d+  ve <- toGVariant e+  gvariantFromTuple [va, vb, vc, vd, ve]++gvariantToFiveTuple :: forall a b c d e.+                       (IsGVariant a, IsGVariant b, IsGVariant c,+                        IsGVariant d, IsGVariant e) =>+                      GVariant -> IO (Maybe (a,b,c,d,e))+gvariantToFiveTuple variant = do+  let expectedType = toGVariantFormatString (undefined :: (a,b,c,d,e))+  maybeChildren <- withExplicitType expectedType gvariant_get_children variant+  if isJust maybeChildren+  then do+    let (Just [a1,a2,a3,a4,a5]) = maybeChildren+    (ma1, ma2, ma3, ma4, ma5) <- (,,,,) <$> fromGVariant a1+                                        <*> fromGVariant a2+                                        <*> fromGVariant a3+                                        <*> fromGVariant a4+                                        <*> fromGVariant a5+    return $ if isJust ma1 && isJust ma2 && isJust ma3 &&+                              isJust ma4 && isJust ma5+             then Just (fromJust ma1, fromJust ma2, fromJust ma3,+                        fromJust ma4, fromJust ma5)+             else Nothing+  else return Nothing
+ Data/GI/Base/ManagedPtr.hs view
@@ -0,0 +1,353 @@+{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}+-- For HasCallStack compatibility+{-# LANGUAGE ImplicitParams, KindSignatures, ConstraintKinds #-}++-- | We wrap most objects in a "managed pointer", which is basically a+-- 'ForeignPtr' of the appropriate type together with a notion of+-- "disowning", which means not running the finalizers passed upon+-- construction of the object upon garbage collection. The routines in+-- this module deal with the memory management of such managed+-- pointers.++module Data.GI.Base.ManagedPtr+    (+    -- * Managed pointers+      newManagedPtr+    , newManagedPtr'+    , withManagedPtr+    , maybeWithManagedPtr+    , withManagedPtrList+    , unsafeManagedPtrGetPtr+    , unsafeManagedPtrCastPtr+    , touchManagedPtr+    , disownManagedPtr++    -- * Safe casting+    , castTo+    , unsafeCastTo++    -- * Wrappers+    , newObject+    , wrapObject+    , unrefObject+    , disownObject+    , newBoxed+    , wrapBoxed+    , copyBoxedPtr+    , freeBoxed+    , disownBoxed+    , wrapPtr+    , newPtr+    , copyPtr+    ) where++#if !MIN_VERSION_base(4,8,0)+import Control.Applicative ((<$>))+#endif+import Control.Monad (when, void)++import Data.Coerce (coerce)+import Data.IORef (newIORef, readIORef, writeIORef, IORef)++import Foreign.C (CInt(..))+import Foreign.Ptr (Ptr, FunPtr, castPtr, nullPtr)+import Foreign.ForeignPtr (FinalizerPtr, touchForeignPtr, newForeignPtr_)+import qualified Foreign.Concurrent as FC+import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)++import Data.GI.Base.BasicTypes+import Data.GI.Base.Utils++import System.IO (hPutStrLn, stderr)++#if MIN_VERSION_base(4,9,0)+import GHC.Stack (HasCallStack, prettyCallStack, callStack)+#elif MIN_VERSION_base(4,8,1)+import GHC.Stack (CallStack)+import GHC.Exts (Constraint)+type HasCallStack = ((?callStack :: CallStack) :: Constraint)+#else+import GHC.Exts (Constraint)+type HasCallStack = (() :: Constraint)+#endif++-- | Thin wrapper over `Foreign.Concurrent.newForeignPtr`.+newManagedPtr :: Ptr a -> IO () -> IO (ManagedPtr a)+newManagedPtr ptr finalizer = do+  let ownedFinalizer :: IORef Bool -> IO ()+      ownedFinalizer boolRef = do+        owned <- readIORef boolRef+        when owned finalizer+  isOwnedRef <- newIORef True+  fPtr <- FC.newForeignPtr ptr (ownedFinalizer isOwnedRef)+  return $ ManagedPtr {+               managedForeignPtr = fPtr+             , managedPtrIsOwned = isOwnedRef+             }++foreign import ccall "dynamic"+   mkFinalizer :: FinalizerPtr a -> Ptr a -> IO ()++-- | Version of `newManagedPtr` taking a `FinalizerPtr` and a+-- corresponding `Ptr`, as in `Foreign.ForeignPtr.newForeignPtr`.+newManagedPtr' :: FinalizerPtr a -> Ptr a -> IO (ManagedPtr a)+newManagedPtr' finalizer ptr = newManagedPtr ptr (mkFinalizer finalizer ptr)++-- | Thin wrapper over `Foreign.Concurrent.newForeignPtr_`.+newManagedPtr_ :: Ptr a -> IO (ManagedPtr a)+newManagedPtr_ ptr = do+  isOwnedRef <- newIORef True+  fPtr <- newForeignPtr_ ptr+  return $ ManagedPtr {+               managedForeignPtr = fPtr+             , managedPtrIsOwned = isOwnedRef+             }++-- | Do not run the finalizers upon garbage collection of the `ManagedPtr`.+disownManagedPtr :: forall a. ManagedPtrNewtype a => a -> IO (Ptr a)+disownManagedPtr managed = do+  ptr <- unsafeManagedPtrGetPtr managed+  writeIORef (managedPtrIsOwned c) False+  return ptr+    where c = coerce managed :: ManagedPtr ()++-- | Perform an IO action on the 'Ptr' inside a managed pointer.+withManagedPtr :: ManagedPtrNewtype a => a -> (Ptr a -> IO c) -> IO c+withManagedPtr managed action = do+  ptr <- unsafeManagedPtrGetPtr managed+  result <- action ptr+  touchManagedPtr managed+  return result++-- | Like `withManagedPtr`, but accepts a `Maybe` type. If the passed+-- value is `Nothing` the inner action will be executed with a+-- `nullPtr` argument.+maybeWithManagedPtr :: ManagedPtrNewtype a => Maybe a -> (Ptr a -> IO c) -> IO c+maybeWithManagedPtr Nothing action = action nullPtr+maybeWithManagedPtr (Just managed) action = do+  ptr <- unsafeManagedPtrGetPtr managed+  result <- action ptr+  touchManagedPtr managed+  return result++-- | Perform an IO action taking a list of 'Ptr' on a list of managed+-- pointers.+withManagedPtrList :: ManagedPtrNewtype a => [a] -> ([Ptr a] -> IO c) -> IO c+withManagedPtrList managedList action = do+  ptrs <- mapM unsafeManagedPtrGetPtr managedList+  result <- action ptrs+  mapM_ touchManagedPtr managedList+  return result++-- | Return the 'Ptr' in a given managed pointer. As the name says,+-- this is potentially unsafe: the given 'Ptr' may only be used+-- /before/ a call to 'touchManagedPtr'. This function is of most+-- interest to the autogenerated bindings, for hand-written code+-- 'withManagedPtr' is almost always a better choice.+unsafeManagedPtrGetPtr :: (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)+unsafeManagedPtrGetPtr = unsafeManagedPtrCastPtr++-- | Same as 'unsafeManagedPtrGetPtr', but is polymorphic on the+-- return type.+unsafeManagedPtrCastPtr :: forall a b. (HasCallStack, ManagedPtrNewtype a) =>+                           a -> IO (Ptr b)+unsafeManagedPtrCastPtr m = do+    let c = coerce m :: ManagedPtr ()+        ptr = (castPtr . unsafeForeignPtrToPtr . managedForeignPtr) c+    owned <- readIORef (managedPtrIsOwned c)+    when (not owned) (notOwnedWarning ptr)+    return ptr++-- | Print a warning when we try to access a disowned foreign ptr.+notOwnedWarning :: HasCallStack => Ptr a -> IO ()+notOwnedWarning ptr = do+  hPutStrLn stderr ("Accessing a disowned pointer <" ++ show ptr+                     ++ ">, this may lead to crashes.\n"+                     ++ callstack)+  where+#if MIN_VERSION_base(4,9,0)+    callstack = prettyCallStack (callStack)+#else+    callstack = "<CallStack only available with GHC 8.0>"+#endif++-- | Ensure that the 'Ptr' in the given managed pointer is still alive+-- (i.e. it has not been garbage collected by the runtime) at the+-- point that this is called.+touchManagedPtr :: forall a. ManagedPtrNewtype a => a -> IO ()+touchManagedPtr m = let c = coerce m :: ManagedPtr ()+                    in (touchForeignPtr . managedForeignPtr) c++-- Safe casting machinery+foreign import ccall unsafe "check_object_type"+    c_check_object_type :: Ptr o -> CGType -> CInt++-- | Cast to the given type, checking that the cast is valid. If it is+-- not, we return `Nothing`. Usage:+--+-- > maybeWidget <- castTo Widget label+castTo :: forall o o'. (GObject o, GObject o') =>+          (ManagedPtr o' -> o') -> o -> IO (Maybe o')+castTo constructor obj =+    withManagedPtr obj $ \objPtr -> do+      GType t <- gobjectType (undefined :: o')+      if c_check_object_type objPtr t /= 1+        then return Nothing+        else Just <$> newObject constructor objPtr++-- | Cast to the given type, assuming that the cast will succeed. This+-- function will call `error` if the cast is illegal.+unsafeCastTo :: forall o o'. (HasCallStack, GObject o, GObject o') =>+                (ManagedPtr o' -> o') -> o -> IO o'+unsafeCastTo constructor obj =+  withManagedPtr obj $ \objPtr -> do+    GType t <- gobjectType (undefined :: o')+    if c_check_object_type objPtr t /= 1+      then do+      srcType <- gobjectType obj >>= gtypeName+      destType <- gobjectType (undefined :: o') >>= gtypeName+      error $ "unsafeCastTo :: invalid conversion from " ++ srcType ++ " to "+        ++ destType ++ " requested."+      else newObject constructor objPtr++-- Reference counting for constructors+foreign import ccall "&dbg_g_object_unref"+    ptr_to_g_object_unref :: FunPtr (Ptr a -> IO ())++foreign import ccall "g_object_ref" g_object_ref ::+    Ptr a -> IO (Ptr a)++-- | Construct a Haskell wrapper for a 'GObject', increasing its+-- reference count.+newObject :: (GObject a, GObject b) => (ManagedPtr a -> a) -> Ptr b -> IO a+newObject constructor ptr = do+  void $ g_object_ref ptr+  fPtr <- newManagedPtr' ptr_to_g_object_unref $ castPtr ptr+  return $! constructor fPtr++foreign import ccall "g_object_ref_sink" g_object_ref_sink ::+    Ptr a -> IO (Ptr a)++-- | Same as 'newObject', but we take ownership of the object. Newly+-- created 'GObject's are typically floating, so we use+-- <https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-ref-sink g_object_ref_sink>.++-- Notice that the+-- semantics here are a little bit subtle: some objects (such as+-- GtkWindow, see the code about "user_ref_count" in gtkwindow.c in+-- the gtk+ distribution) are created /without/ the floating flag,+-- since they own a reference to themselves. So, wrapping them is+-- really about adding a ref. If we add the ref, when Haskell drops+-- the last ref to the 'GObject' it will /g_object_unref/, and the+-- window will /g_object_unref/ itself upon destruction, so by the end+-- we don't leak memory. If we don't add the ref, there will be two+-- /g_object_unrefs/ acting on the object (one from Haskell and one from+-- the GtkWindow destroy) when the object is destroyed and the second+-- one will give a segfault.+--+-- This is the story for GInitiallyUnowned objects (e.g. anything that+-- is a descendant from GtkWidget). For objects that are not initially+-- floating (i.e. not descendents of GInitiallyUnowned) we simply take+-- control of the reference.+wrapObject :: forall a b. (GObject a, GObject b) =>+              (ManagedPtr a -> a) -> Ptr b -> IO a+wrapObject constructor ptr = do+  when (gobjectIsInitiallyUnowned (undefined :: a)) $+       void $ g_object_ref_sink ptr+  fPtr <- newManagedPtr' ptr_to_g_object_unref $ castPtr ptr+  return $! constructor fPtr+++foreign import ccall "dbg_g_object_unref"+        dbg_g_object_unref :: Ptr a -> IO ()++-- | Decrease the reference count of the given 'GObject'. The memory+-- associated with the object may be released if the reference count+-- reaches 0.+unrefObject :: GObject a => a -> IO ()+unrefObject obj = withManagedPtr obj dbg_g_object_unref++-- | Print some debug info (if the right environment valiable is set)+-- about the object being disowned.+foreign import ccall "dbg_g_object_disown"+        dbg_g_object_disown :: Ptr a -> IO ()++-- | Disown a GObject, that is, do not unref the associated foreign+-- GObject when the Haskell object gets garbage collected. Returns the+-- pointer to the underlying GObject.+disownObject :: GObject a => a -> IO (Ptr b)+disownObject obj = withManagedPtr obj $ \ptr -> do+                     dbg_g_object_disown ptr+                     castPtr <$> disownManagedPtr obj++foreign import ccall "boxed_free_helper" boxed_free_helper ::+    CGType -> Ptr a -> IO ()++foreign import ccall "g_boxed_copy" g_boxed_copy ::+    CGType -> Ptr a -> IO (Ptr a)++-- | Construct a Haskell wrapper for the given boxed object. We make a+-- copy of the object.+newBoxed :: forall a. BoxedObject a => (ManagedPtr a -> a) -> Ptr a -> IO a+newBoxed constructor ptr = do+  GType gtype <- boxedType (undefined :: a)+  ptr' <- g_boxed_copy gtype ptr+  fPtr <- newManagedPtr ptr' (boxed_free_helper gtype ptr')+  return $! constructor fPtr++-- | Like 'newBoxed', but we do not make a copy (we "steal" the passed+-- object, so now it is managed by the Haskell runtime).+wrapBoxed :: forall a. BoxedObject a => (ManagedPtr a -> a) -> Ptr a -> IO a+wrapBoxed constructor ptr = do+  GType gtype <- boxedType (undefined :: a)+  fPtr <- newManagedPtr ptr (boxed_free_helper gtype ptr)+  return $! constructor fPtr++-- | Like 'copyBoxed', but acting directly on a pointer, instead of a+-- managed pointer.+copyBoxedPtr :: forall a. BoxedObject a => Ptr a -> IO (Ptr a)+copyBoxedPtr ptr = do+  GType gtype <- boxedType (undefined :: a)+  g_boxed_copy gtype ptr++foreign import ccall "g_boxed_free" g_boxed_free ::+    CGType -> Ptr a -> IO ()++-- | Free the memory associated with a boxed object+freeBoxed :: forall a. BoxedObject a => a -> IO ()+freeBoxed boxed = do+  GType gtype <- boxedType (undefined :: a)+  ptr <- unsafeManagedPtrGetPtr boxed+  g_boxed_free gtype ptr+  touchManagedPtr boxed++-- | Disown a boxed object, that is, do not free the associated+-- foreign GBoxed when the Haskell object gets garbage+-- collected. Returns the pointer to the underlying `BoxedObject`.+disownBoxed :: BoxedObject a => a -> IO (Ptr a)+disownBoxed = disownManagedPtr++-- | Wrap a pointer, taking ownership of it.+wrapPtr :: WrappedPtr a => (ManagedPtr a -> a) -> Ptr a -> IO a+wrapPtr constructor ptr = do+  fPtr <- case wrappedPtrFree of+            Nothing -> newManagedPtr_ ptr+            Just finalizer -> newManagedPtr' finalizer ptr+  return $! constructor fPtr++-- | Wrap a pointer, making a copy of the data.+newPtr :: WrappedPtr a => (ManagedPtr a -> a) -> Ptr a -> IO a+newPtr constructor ptr = do+  ptr' <- wrappedPtrCopy ptr+  fPtr <- case wrappedPtrFree of+            Nothing -> newManagedPtr_ ptr+            Just finalizer -> newManagedPtr' finalizer ptr'+  return $! constructor fPtr++-- | Make a copy of a wrapped pointer using @memcpy@ into a freshly+-- allocated memory region of the given size.+copyPtr :: WrappedPtr a => Int -> Ptr a -> IO (Ptr a)+copyPtr size ptr = do+  ptr' <- wrappedPtrCalloc+  memcpy ptr' ptr size+  return ptr'
+ Data/GI/Base/Overloading.hs view
@@ -0,0 +1,263 @@+{-# LANGUAGE TypeOperators, KindSignatures, DataKinds, PolyKinds,+             TypeFamilies, UndecidableInstances, EmptyDataDecls,+             MultiParamTypeClasses, FlexibleInstances, ConstraintKinds #-}++-- | Helpers for dealing with `GObject`s.++module Data.GI.Base.Overloading+    ( -- * Type level inheritance+      ParentTypes+    , IsDescendantOf+#if MIN_VERSION_base(4,9,0)+    , UnknownAncestorError+#endif++    -- * Looking up attributes in parent types+    , AttributeList+    , HasAttributeList+    , ResolveAttribute+    , HasAttribute+    , HasAttr++    -- * Looking up signals in parent types+    , SignalList+    , ResolveSignal+    , HasSignal++    -- * Looking up methods in parent types+    , MethodInfo(..)+    , MethodProxy(..)+    , MethodResolutionFailed++    -- * Overloaded labels+    , IsLabelProxy(..)++#if MIN_VERSION_base(4,9,0)+    , module GHC.OverloadedLabels       -- Reexported for convenience+#endif+    ) where++import GHC.Exts (Constraint)+import GHC.TypeLits+import Data.Proxy (Proxy)++#if MIN_VERSION_base(4,9,0)+import GHC.OverloadedLabels (IsLabel(..))+#endif++-- | Support for overloaded labels in ghc < 8.0. This is like the+-- `IsLabel` class introduced in ghc 8.0 (for use with the+-- OverloadedLabels extension) with the difference that the `Proxy`+-- argument is lifted. (Using the unlifted Proxy# type in user code is+-- a bit of a pain, hence the choice.)+class IsLabelProxy (x :: Symbol) a where+  fromLabelProxy :: Proxy x -> a++-- | Join two lists.+type family JoinLists (as :: [a]) (bs :: [a]) :: [a] where+    JoinLists '[] bs = bs+    JoinLists (a ': as) bs = a ': JoinLists as bs++-- | Look in the given list of (symbol, tag) tuples for the tag+-- corresponding to the given symbol. If not found raise the given+-- type error.+type family FindElement (m :: Symbol) (ms :: [(Symbol, *)])+#if !MIN_VERSION_base(4,9,0)+    (typeError :: *)+#else+    (typeError :: ErrorMessage)+#endif+    :: * where+    FindElement m '[] typeError =+#if !MIN_VERSION_base(4,9,0)+        typeError+#else+        TypeError typeError+#endif+    FindElement m ('(m, o) ': ms) typeError = o+    FindElement m ('(m', o) ': ms) typeError = FindElement m ms typeError++-- | Result of a ancestor check. Basically a Bool type with a bit of+-- extra info in order to improve typechecker error messages.+data AncestorCheck t a = HasAncestor a t+#if !MIN_VERSION_base(4,9,0)+                       | DoesNotHaveRequiredAncestor Symbol t Symbol a+#endif++#if MIN_VERSION_base(4,9,0)+-- | Type error to be generated when an ancestor check fails.+type family UnknownAncestorError (a :: *) (t :: *) where+    UnknownAncestorError a t =+        TypeError ('Text "Required ancestor ‘" ':<>: 'ShowType a+                   ':<>: 'Text "’ not found for type ‘"+                   ':<>: 'ShowType t ':<>: 'Text "’.")+#endif++-- | Check whether a type appears in a list. We specialize the+-- names/types a bit so the error messages are more informative.+type family CheckForAncestorType t (a :: *) (as :: [*]) :: AncestorCheck * * where+    CheckForAncestorType t a '[] =+#if !MIN_VERSION_base(4,9,0)+        'DoesNotHaveRequiredAncestor "Error: Required ancestor" a "not found for type" t+#else+        UnknownAncestorError a t+#endif+    CheckForAncestorType t a (a ': as) = 'HasAncestor a t+    CheckForAncestorType t a (b ': as) = CheckForAncestorType t a as++-- | Check that a type is in the list of `GObjectParents` of another+-- `GObject`-derived type.+type family IsDescendantOf (parent :: *) (descendant :: *) :: Constraint where+    -- Every object is defined to be a descendant of itself.+    IsDescendantOf d d = () ~ ()+    IsDescendantOf p d = CheckForAncestorType d p (ParentTypes d) ~ 'HasAncestor p d++-- | The direct parents of this object: its direct parent type, if any,+-- and the interfaces it implements. The interfaces inherited from+-- parent types can be omitted.+type family ParentTypes a :: [*]++-- | The list of attributes defined for a given type. Each element of+-- the list is a tuple, with the first element of the tuple the name+-- of the attribute, and the second the type encoding the information+-- of the attribute. This type will be an instance of `AttrInfo`.+type family AttributeList a :: [(Symbol, *)]++-- | A constraint on a type, to be fulfilled whenever it has a type+-- instance for `AttributeList`. This is here for nicer error+-- reporting.+class HasAttributeList a++#if MIN_VERSION_base(4,9,0)+-- Default instance, which will give rise to an error for types+-- without an associated `AttributeList`.+instance {-# OVERLAPPABLE #-}+    TypeError ('Text "Type ‘" ':<>: 'ShowType a ':<>:+               'Text "’ does not have any known attributes.")+    => HasAttributeList a+#endif++#if !MIN_VERSION_base(4,9,0)+-- | Datatype returned when the attribute is not found, hopefully making+-- the resulting error messages somewhat clearer.+data UnknownAttribute (msg1 :: Symbol) (s :: Symbol) (msg2 :: Symbol) (o :: *)+#endif++-- | Return the type encoding the attribute information for a given+-- type and attribute.+type family ResolveAttribute (s :: Symbol) (o :: *) :: * where+    ResolveAttribute s o = FindElement s (AttributeList o)+#if !MIN_VERSION_base(4,9,0)+                           (UnknownAttribute "Error: could not find attribute" s "for object" o)+#else+                           ('Text "Unknown attribute ‘" ':<>:+                            'Text s ':<>: 'Text "’ for object ‘" ':<>:+                            'ShowType o ':<>: 'Text "’.")+#endif++-- | Whether a given type is in the given list. If found, return+-- @success@, otherwise return @failure@.+type family IsElem (e :: Symbol) (es :: [(Symbol, *)]) (success :: k)+#if !MIN_VERSION_base(4,9,0)+    (failure :: k)+#else+    (failure :: ErrorMessage)+#endif+        :: k where+    IsElem e '[] success failure =+#if !MIN_VERSION_base(4,9,0)+        failure+#else+        TypeError failure+#endif+    IsElem e ( '(e, t) ': es) success failure = success+    IsElem e ( '(other, t) ': es) s f = IsElem e es s f++-- | Isomorphic to Bool, but having some extra debug information.+data AttributeCheck a t = HasAttribute+#if !MIN_VERSION_base(4,9,0)+                        | DoesNotHaveAttribute Symbol a Symbol t+#endif++-- | A constraint imposing that the given object has the given attribute.+type family HasAttribute (attr :: Symbol) (o :: *) where+    HasAttribute attr o = IsElem attr (AttributeList o)+                          'HasAttribute+#if !MIN_VERSION_base(4,9,0)+                          ('DoesNotHaveAttribute "Error: attribute" attr "not found for type" o)+#else+                          ('Text "Attribute ‘" ':<>: 'Text attr ':<>:+                           'Text "’ not found for type ‘" ':<>:+                           'ShowType o ':<>: 'Text "’.")+#endif+                          ~ 'HasAttribute++-- | A constraint that enforces that the given type has a given attribute.+class HasAttr (attr :: Symbol) (o :: *)+instance HasAttribute attr o => HasAttr attr o++-- | The list of signals defined for a given type. Each element of+-- the list is a tuple, with the first element of the tuple the name+-- of the signal, and the second the type encoding the information of+-- the signal. This type will be an instance of `SignalInfo`.+type family SignalList a :: [(Symbol, *)]++#if !MIN_VERSION_base(4,9,0)+-- | Datatype returned when the signal is not found, hopefully making+-- the resulting error messages somewhat clearer.+data UnknownSignal (msg1 :: Symbol) (s :: Symbol) (msg2 :: Symbol) (o :: *)+#endif++-- | Return the type encoding the signal information for a given+-- type and signal.+type family ResolveSignal (s :: Symbol) (o :: *) :: * where+    ResolveSignal s o = FindElement s (SignalList o)+#if !MIN_VERSION_base(4,9,0)+                        (UnknownSignal "Error: could not find signal" s "for object" o)+#else+                        ('Text "Unknown signal ‘" ':<>:+                         'Text s ':<>: 'Text "’ for object ‘" ':<>:+                         'ShowType o ':<>: 'Text "’.")+#endif++-- | Isomorphic to Bool, but having some extra debug information.+data SignalCheck s t = HasSignal+#if !MIN_VERSION_base(4,9,0)+                     | DoesNotHaveSignal Symbol s Symbol t+#endif++-- | A constraint enforcing that the signal exists for the given+-- object, or one of its ancestors.+type family HasSignal (s :: Symbol) (o :: *) where+    HasSignal s o = IsElem s (SignalList o)+                    'HasSignal+#if !MIN_VERSION_base(4,9,0)+                    ('DoesNotHaveSignal "Error: signal" s "not found for type" o)+#else+                    ('Text "Signal ‘" ':<>: 'Text s ':<>:+                     'Text "’ not found for type ‘" ':<>:+                     'ShowType o ':<>: 'Text "’.")+#endif+                    ~ 'HasSignal++-- | Class for types containing the information about an overloaded+-- method of type `o -> s`.+class MethodInfo i o s where+    overloadedMethod :: MethodProxy i -> o -> s++-- | Proxy for passing a type to `overloadedMethod`. We do not use+-- `Data.Proxy.Proxy` directly since it clashes with types defined in+-- the autogenerated bindings.+data MethodProxy a = MethodProxy++#if !MIN_VERSION_base(4,9,0)+-- | Datatype returned when the method is not found, hopefully making+-- the resulting error messages somewhat clearer.+data MethodResolutionFailed (label :: Symbol) (o :: *)+#else+type family MethodResolutionFailed (method :: Symbol) (o :: *) where+    MethodResolutionFailed m o =+        TypeError ('Text "Unknown method ‘" ':<>:+                   'Text m ':<>: 'Text "’ for type ‘" ':<>:+                   'ShowType o ':<>: 'Text "’.")+#endif
+ Data/GI/Base/Properties.hsc view
@@ -0,0 +1,521 @@+{-# LANGUAGE ScopedTypeVariables #-}++module Data.GI.Base.Properties+    ( setObjectPropertyString+    , setObjectPropertyStringArray+    , setObjectPropertyPtr+    , setObjectPropertyInt+    , setObjectPropertyUInt+    , setObjectPropertyLong+    , setObjectPropertyULong+    , setObjectPropertyInt32+    , setObjectPropertyUInt32+    , setObjectPropertyInt64+    , setObjectPropertyUInt64+    , setObjectPropertyFloat+    , setObjectPropertyDouble+    , setObjectPropertyBool+    , setObjectPropertyGType+    , setObjectPropertyObject+    , setObjectPropertyBoxed+    , setObjectPropertyEnum+    , setObjectPropertyFlags+    , setObjectPropertyVariant+    , setObjectPropertyByteArray+    , setObjectPropertyPtrGList+    , setObjectPropertyHash++    , getObjectPropertyString+    , getObjectPropertyStringArray+    , getObjectPropertyPtr+    , getObjectPropertyInt+    , getObjectPropertyUInt+    , getObjectPropertyLong+    , getObjectPropertyULong+    , getObjectPropertyInt32+    , getObjectPropertyUInt32+    , getObjectPropertyInt64+    , getObjectPropertyUInt64+    , getObjectPropertyFloat+    , getObjectPropertyDouble+    , getObjectPropertyBool+    , getObjectPropertyGType+    , getObjectPropertyObject+    , getObjectPropertyBoxed+    , getObjectPropertyEnum+    , getObjectPropertyFlags+    , getObjectPropertyVariant+    , getObjectPropertyByteArray+    , getObjectPropertyPtrGList+    , getObjectPropertyHash++    , constructObjectPropertyString+    , constructObjectPropertyStringArray+    , constructObjectPropertyPtr+    , constructObjectPropertyInt+    , constructObjectPropertyUInt+    , constructObjectPropertyLong+    , constructObjectPropertyULong+    , constructObjectPropertyInt32+    , constructObjectPropertyUInt32+    , constructObjectPropertyInt64+    , constructObjectPropertyUInt64+    , constructObjectPropertyFloat+    , constructObjectPropertyDouble+    , constructObjectPropertyBool+    , constructObjectPropertyGType+    , constructObjectPropertyObject+    , constructObjectPropertyBoxed+    , constructObjectPropertyEnum+    , constructObjectPropertyFlags+    , constructObjectPropertyVariant+    , constructObjectPropertyByteArray+    , constructObjectPropertyPtrGList+    , constructObjectPropertyHash+    ) where++#if !MIN_VERSION_base(4,8,0)+import Control.Applicative ((<$>))+#endif+import Control.Monad ((>=>))++import qualified Data.ByteString.Char8 as B+import Data.Text (Text)+import Data.Proxy (Proxy(..))++import Data.GI.Base.BasicTypes+import Data.GI.Base.BasicConversions+import Data.GI.Base.ManagedPtr+import Data.GI.Base.GValue+import Data.GI.Base.GVariant (newGVariantFromPtr)+import Data.GI.Base.Utils (freeMem, convertIfNonNull)++import Foreign (Ptr, Int32, Word32, Int64, Word64, nullPtr)+import Foreign.C (CString, withCString)+import Foreign.C.Types (CInt, CUInt, CLong, CULong)++#include <glib-object.h>++foreign import ccall "g_object_set_property" g_object_set_property ::+    Ptr a -> CString -> Ptr GValue -> IO ()++setObjectProperty :: GObject a => a -> String -> b ->+                     (GValue -> b -> IO ()) -> GType -> IO ()+setObjectProperty obj propName propValue setter (GType gtype) = do+  gvalue <- buildGValue (GType gtype) setter propValue+  withManagedPtr obj $ \objPtr ->+      withCString propName $ \cPropName ->+          withManagedPtr gvalue $ \gvalueptr ->+              g_object_set_property objPtr cPropName gvalueptr++foreign import ccall "g_object_get_property" g_object_get_property ::+    Ptr a -> CString -> Ptr GValue -> IO ()++getObjectProperty :: GObject a => a -> String ->+                     (GValue -> IO b) -> GType -> IO b+getObjectProperty obj propName getter gtype = do+  gvalue <- newGValue gtype+  withManagedPtr obj $ \objPtr ->+      withCString propName $ \cPropName ->+          withManagedPtr gvalue $ \gvalueptr ->+              g_object_get_property objPtr cPropName gvalueptr+  getter gvalue++constructObjectProperty :: String -> b -> (GValue -> b -> IO ()) ->+                           GType -> IO (GValueConstruct o)+constructObjectProperty propName propValue setter gtype = do+  gvalue <- buildGValue gtype setter propValue+  return (GValueConstruct propName gvalue)++setObjectPropertyString :: GObject a =>+                           a -> String -> Maybe Text -> IO ()+setObjectPropertyString obj propName str =+    setObjectProperty obj propName str set_string gtypeString++constructObjectPropertyString :: String -> Maybe Text ->+                                 IO (GValueConstruct o)+constructObjectPropertyString propName str =+    constructObjectProperty propName str set_string gtypeString++getObjectPropertyString :: GObject a =>+                           a -> String -> IO (Maybe Text)+getObjectPropertyString obj propName =+    getObjectProperty obj propName get_string gtypeString++setObjectPropertyPtr :: GObject a =>+                        a -> String -> Ptr b -> IO ()+setObjectPropertyPtr obj propName ptr =+    setObjectProperty obj propName ptr set_pointer gtypePointer++constructObjectPropertyPtr :: String -> Ptr b ->+                              IO (GValueConstruct o)+constructObjectPropertyPtr propName ptr =+    constructObjectProperty propName ptr set_pointer gtypePointer++getObjectPropertyPtr :: GObject a =>+                        a -> String -> IO (Ptr b)+getObjectPropertyPtr obj propName =+    getObjectProperty obj propName get_pointer gtypePointer++setObjectPropertyInt :: GObject a =>+                         a -> String -> CInt -> IO ()+setObjectPropertyInt obj propName int =+    setObjectProperty obj propName int set_int gtypeInt++constructObjectPropertyInt :: String -> CInt ->+                              IO (GValueConstruct o)+constructObjectPropertyInt propName int =+    constructObjectProperty propName int set_int gtypeInt++getObjectPropertyInt :: GObject a => a -> String -> IO CInt+getObjectPropertyInt obj propName =+    getObjectProperty obj propName get_int gtypeInt++setObjectPropertyUInt :: GObject a =>+                          a -> String -> CUInt -> IO ()+setObjectPropertyUInt obj propName uint =+    setObjectProperty obj propName uint set_uint gtypeUInt++constructObjectPropertyUInt :: String -> CUInt ->+                                IO (GValueConstruct o)+constructObjectPropertyUInt propName uint =+    constructObjectProperty propName uint set_uint gtypeUInt++getObjectPropertyUInt :: GObject a => a -> String -> IO CUInt+getObjectPropertyUInt obj propName =+    getObjectProperty obj propName get_uint gtypeUInt++setObjectPropertyLong :: GObject a =>+                         a -> String -> CLong -> IO ()+setObjectPropertyLong obj propName int =+    setObjectProperty obj propName int set_long gtypeLong++constructObjectPropertyLong :: String -> CLong ->+                               IO (GValueConstruct o)+constructObjectPropertyLong propName int =+    constructObjectProperty propName int set_long gtypeLong++getObjectPropertyLong :: GObject a => a -> String -> IO CLong+getObjectPropertyLong obj propName =+    getObjectProperty obj propName get_long gtypeLong++setObjectPropertyULong :: GObject a =>+                          a -> String -> CULong -> IO ()+setObjectPropertyULong obj propName uint =+    setObjectProperty obj propName uint set_ulong gtypeULong++constructObjectPropertyULong :: String -> CULong ->+                                IO (GValueConstruct o)+constructObjectPropertyULong propName uint =+    constructObjectProperty propName uint set_ulong gtypeULong++getObjectPropertyULong :: GObject a => a -> String -> IO CULong+getObjectPropertyULong obj propName =+    getObjectProperty obj propName get_ulong gtypeULong++setObjectPropertyInt32 :: GObject a =>+                          a -> String -> Int32 -> IO ()+setObjectPropertyInt32 obj propName int32 =+    setObjectProperty obj propName int32 set_int32 gtypeInt++constructObjectPropertyInt32 :: String -> Int32 ->+                                IO (GValueConstruct o)+constructObjectPropertyInt32 propName int32 =+    constructObjectProperty propName int32 set_int32 gtypeInt++getObjectPropertyInt32 :: GObject a => a -> String -> IO Int32+getObjectPropertyInt32 obj propName =+    getObjectProperty obj propName get_int32 gtypeInt++setObjectPropertyUInt32 :: GObject a =>+                          a -> String -> Word32 -> IO ()+setObjectPropertyUInt32 obj propName uint32 =+    setObjectProperty obj propName uint32 set_uint32 gtypeUInt++constructObjectPropertyUInt32 :: String -> Word32 ->+                                 IO (GValueConstruct o)+constructObjectPropertyUInt32 propName uint32 =+    constructObjectProperty propName uint32 set_uint32 gtypeUInt++getObjectPropertyUInt32 :: GObject a => a -> String -> IO Word32+getObjectPropertyUInt32 obj propName =+    getObjectProperty obj propName get_uint32 gtypeUInt++setObjectPropertyInt64 :: GObject a =>+                          a -> String -> Int64 -> IO ()+setObjectPropertyInt64 obj propName int64 =+    setObjectProperty obj propName int64 set_int64 gtypeInt64++constructObjectPropertyInt64 :: String -> Int64 ->+                                IO (GValueConstruct o)+constructObjectPropertyInt64 propName int64 =+    constructObjectProperty propName int64 set_int64 gtypeInt64++getObjectPropertyInt64 :: GObject a => a -> String -> IO Int64+getObjectPropertyInt64 obj propName =+    getObjectProperty obj propName get_int64 gtypeInt64++setObjectPropertyUInt64 :: GObject a =>+                          a -> String -> Word64 -> IO ()+setObjectPropertyUInt64 obj propName uint64 =+    setObjectProperty obj propName uint64 set_uint64 gtypeUInt64++constructObjectPropertyUInt64 :: String -> Word64 ->+                                 IO (GValueConstruct o)+constructObjectPropertyUInt64 propName uint64 =+    constructObjectProperty propName uint64 set_uint64 gtypeUInt64++getObjectPropertyUInt64 :: GObject a => a -> String -> IO Word64+getObjectPropertyUInt64 obj propName =+    getObjectProperty obj propName get_uint64 gtypeUInt64++setObjectPropertyFloat :: GObject a =>+                           a -> String -> Float -> IO ()+setObjectPropertyFloat obj propName float =+    setObjectProperty obj propName float set_float gtypeFloat++constructObjectPropertyFloat :: String -> Float ->+                                 IO (GValueConstruct o)+constructObjectPropertyFloat propName float =+    constructObjectProperty propName float set_float gtypeFloat++getObjectPropertyFloat :: GObject a =>+                           a -> String -> IO Float+getObjectPropertyFloat obj propName =+    getObjectProperty obj propName get_float gtypeFloat++setObjectPropertyDouble :: GObject a =>+                            a -> String -> Double -> IO ()+setObjectPropertyDouble obj propName double =+    setObjectProperty obj propName double set_double gtypeDouble++constructObjectPropertyDouble :: String -> Double ->+                                  IO (GValueConstruct o)+constructObjectPropertyDouble propName double =+    constructObjectProperty propName double set_double gtypeDouble++getObjectPropertyDouble :: GObject a =>+                            a -> String -> IO Double+getObjectPropertyDouble obj propName =+    getObjectProperty obj propName get_double gtypeDouble++setObjectPropertyBool :: GObject a =>+                         a -> String -> Bool -> IO ()+setObjectPropertyBool obj propName bool =+    setObjectProperty obj propName bool set_boolean gtypeBoolean++constructObjectPropertyBool :: String -> Bool -> IO (GValueConstruct o)+constructObjectPropertyBool propName bool =+    constructObjectProperty propName bool set_boolean gtypeBoolean++getObjectPropertyBool :: GObject a => a -> String -> IO Bool+getObjectPropertyBool obj propName =+    getObjectProperty obj propName get_boolean gtypeBoolean++setObjectPropertyGType :: GObject a =>+                         a -> String -> GType -> IO ()+setObjectPropertyGType obj propName gtype =+    setObjectProperty obj propName gtype set_gtype gtypeGType++constructObjectPropertyGType :: String -> GType -> IO (GValueConstruct o)+constructObjectPropertyGType propName bool =+    constructObjectProperty propName bool set_gtype gtypeGType++getObjectPropertyGType :: GObject a => a -> String -> IO GType+getObjectPropertyGType obj propName =+    getObjectProperty obj propName get_gtype gtypeGType++setObjectPropertyObject :: forall a b. (GObject a, GObject b) =>+                           a -> String -> Maybe b -> IO ()+setObjectPropertyObject obj propName maybeObject = do+  gtype <- gobjectType (undefined :: b)+  maybeWithManagedPtr maybeObject $ \objectPtr ->+      setObjectProperty obj propName objectPtr set_object gtype++constructObjectPropertyObject :: forall a o. GObject a =>+                                 String -> Maybe a -> IO (GValueConstruct o)+constructObjectPropertyObject propName maybeObject = do+  gtype <- gobjectType (undefined :: a)+  maybeWithManagedPtr maybeObject $ \objectPtr ->+      constructObjectProperty propName objectPtr set_object gtype++getObjectPropertyObject :: forall a b. (GObject a, GObject b) =>+                           a -> String -> (ManagedPtr b -> b) -> IO (Maybe b)+getObjectPropertyObject obj propName constructor = do+  gtype <- gobjectType (undefined :: b)+  getObjectProperty obj propName+                        (\val -> (get_object val :: IO (Ptr b))+                            >>= flip convertIfNonNull (newObject constructor))+                      gtype++setObjectPropertyBoxed :: forall a b. (GObject a, BoxedObject b) =>+                          a -> String -> Maybe b -> IO ()+setObjectPropertyBoxed obj propName maybeBoxed = do+  gtype <- boxedType (undefined :: b)+  maybeWithManagedPtr maybeBoxed $ \boxedPtr ->+        setObjectProperty obj propName boxedPtr set_boxed gtype++constructObjectPropertyBoxed :: forall a o. (BoxedObject a) =>+                                String -> Maybe a -> IO (GValueConstruct o)+constructObjectPropertyBoxed propName maybeBoxed = do+  gtype <- boxedType (undefined :: a)+  maybeWithManagedPtr maybeBoxed $ \boxedPtr ->+      constructObjectProperty propName boxedPtr set_boxed gtype++getObjectPropertyBoxed :: forall a b. (GObject a, BoxedObject b) =>+                          a -> String -> (ManagedPtr b -> b) -> IO (Maybe b)+getObjectPropertyBoxed obj propName constructor = do+  gtype <- boxedType (undefined :: b)+  getObjectProperty obj propName (get_boxed >=>+                                  flip convertIfNonNull (newBoxed constructor))+                    gtype++setObjectPropertyStringArray :: GObject a =>+                                a -> String -> Maybe [Text] -> IO ()+setObjectPropertyStringArray obj propName Nothing =+  setObjectProperty obj propName nullPtr set_boxed gtypeStrv+setObjectPropertyStringArray obj propName (Just strv) = do+  cStrv <- packZeroTerminatedUTF8CArray strv+  setObjectProperty obj propName cStrv set_boxed gtypeStrv+  mapZeroTerminatedCArray freeMem cStrv+  freeMem cStrv++constructObjectPropertyStringArray :: String -> Maybe [Text] ->+                                      IO (GValueConstruct o)+constructObjectPropertyStringArray propName Nothing =+  constructObjectProperty propName nullPtr set_boxed gtypeStrv+constructObjectPropertyStringArray propName (Just strv) = do+  cStrv <- packZeroTerminatedUTF8CArray strv+  result <- constructObjectProperty propName cStrv set_boxed gtypeStrv+  mapZeroTerminatedCArray freeMem cStrv+  freeMem cStrv+  return result++getObjectPropertyStringArray :: GObject a => a -> String -> IO (Maybe [Text])+getObjectPropertyStringArray obj propName =+    getObjectProperty obj propName+                      (get_boxed >=>+                       flip convertIfNonNull unpackZeroTerminatedUTF8CArray)+                      gtypeStrv++setObjectPropertyEnum :: (GObject a, Enum b, BoxedEnum b) =>+                         a -> String -> b -> IO ()+setObjectPropertyEnum obj propName enum = do+  gtype <- boxedEnumType enum+  let cEnum = (fromIntegral . fromEnum) enum+  setObjectProperty obj propName cEnum set_enum gtype++constructObjectPropertyEnum :: (Enum a, BoxedEnum a) =>+                               String -> a -> IO (GValueConstruct o)+constructObjectPropertyEnum propName enum = do+  gtype <- boxedEnumType enum+  let cEnum = (fromIntegral . fromEnum) enum+  constructObjectProperty propName cEnum set_enum gtype++getObjectPropertyEnum :: forall a b. (GObject a,+                                      Enum b, BoxedEnum b) =>+                         a -> String -> IO b+getObjectPropertyEnum obj propName = do+  gtype <- boxedEnumType (undefined :: b)+  getObjectProperty obj propName+                    (\val -> toEnum . fromIntegral <$> get_enum val)+                    gtype++setObjectPropertyFlags :: forall a b. (IsGFlag b, BoxedFlags b, GObject a) =>+                          a -> String -> [b] -> IO ()+setObjectPropertyFlags obj propName flags = do+  let cFlags = gflagsToWord flags+  gtype <- boxedFlagsType (Proxy :: Proxy b)+  setObjectProperty obj propName cFlags set_flags gtype++constructObjectPropertyFlags :: forall a o. (IsGFlag a, BoxedFlags a)+                                => String -> [a] -> IO (GValueConstruct o)+constructObjectPropertyFlags propName flags = do+  let cFlags = gflagsToWord flags+  gtype <- boxedFlagsType (Proxy :: Proxy a)+  constructObjectProperty propName cFlags set_flags gtype++getObjectPropertyFlags :: forall a b. (GObject a, IsGFlag b, BoxedFlags b) =>+                          a -> String -> IO [b]+getObjectPropertyFlags obj propName = do+  gtype <- boxedFlagsType (Proxy :: Proxy b)+  getObjectProperty obj propName+                        (\val -> wordToGFlags <$> get_flags val)+                        gtype++setObjectPropertyVariant :: GObject a =>+                            a -> String -> Maybe GVariant -> IO ()+setObjectPropertyVariant obj propName maybeVariant =+    maybeWithManagedPtr maybeVariant $ \variantPtr ->+        setObjectProperty obj propName variantPtr set_variant gtypeVariant++constructObjectPropertyVariant :: String -> Maybe GVariant+                               -> IO (GValueConstruct o)+constructObjectPropertyVariant propName maybeVariant =+    maybeWithManagedPtr maybeVariant $ \objPtr ->+        constructObjectProperty propName objPtr set_variant gtypeVariant++getObjectPropertyVariant :: GObject a => a -> String ->+                            IO (Maybe GVariant)+getObjectPropertyVariant obj propName =+    getObjectProperty obj propName (get_variant >=>+                                    flip convertIfNonNull newGVariantFromPtr)+                      gtypeVariant++setObjectPropertyByteArray :: GObject a =>+                              a -> String -> Maybe B.ByteString -> IO ()+setObjectPropertyByteArray obj propName Nothing =+    setObjectProperty obj propName nullPtr set_boxed gtypeByteArray+setObjectPropertyByteArray obj propName (Just bytes) = do+  packed <- packGByteArray bytes+  setObjectProperty obj propName packed set_boxed gtypeByteArray+  unrefGByteArray packed++constructObjectPropertyByteArray :: String -> Maybe B.ByteString ->+                                    IO (GValueConstruct o)+constructObjectPropertyByteArray propName Nothing =+    constructObjectProperty propName nullPtr set_boxed gtypeByteArray+constructObjectPropertyByteArray propName (Just bytes) = do+  packed <- packGByteArray bytes+  result <- constructObjectProperty propName packed set_boxed gtypeByteArray+  unrefGByteArray packed+  return result++getObjectPropertyByteArray :: GObject a =>+                              a -> String -> IO (Maybe B.ByteString)+getObjectPropertyByteArray obj propName =+    getObjectProperty obj propName (get_boxed >=>+                                    flip convertIfNonNull unpackGByteArray)+                      gtypeByteArray++setObjectPropertyPtrGList :: GObject a =>+                              a -> String -> [Ptr b] -> IO ()+setObjectPropertyPtrGList obj propName ptrs = do+  packed <- packGList ptrs+  setObjectProperty obj propName packed set_boxed gtypePointer+  g_list_free packed++constructObjectPropertyPtrGList :: String -> [Ptr a] ->+                                    IO (GValueConstruct o)+constructObjectPropertyPtrGList propName ptrs = do+  packed <- packGList ptrs+  result <- constructObjectProperty propName packed set_boxed gtypePointer+  g_list_free packed+  return result++getObjectPropertyPtrGList :: GObject a =>+                              a -> String -> IO [Ptr b]+getObjectPropertyPtrGList obj propName =+    getObjectProperty obj propName (get_pointer >=> unpackGList) gtypePointer++setObjectPropertyHash :: GObject a => a -> String -> b -> IO ()+setObjectPropertyHash =+    error $ "Setting GHashTable properties not supported yet."++constructObjectPropertyHash :: String -> b -> IO (GValueConstruct o)+constructObjectPropertyHash =+    error $ "Constructing GHashTable properties not supported yet."++getObjectPropertyHash :: GObject a => a -> String -> IO b+getObjectPropertyHash =+    error $ "Getting GHashTable properties not supported yet."
+ Data/GI/Base/ShortPrelude.hs view
@@ -0,0 +1,93 @@+-- | The Haskell Prelude exports a number of symbols that can easily+-- collide with functions appearing in bindings. The generated code+-- requires just a small subset of the functions in the Prelude,+-- together with some of the functionality in Data.GI.Base, we+-- reexport this explicitly here.+module Data.GI.Base.ShortPrelude+    ( module Data.Char+    , module Data.Int+    , module Data.Word+    , module Data.ByteString.Char8+    , module Foreign.C+    , module Foreign.Ptr+    , module Foreign.ForeignPtr+    , module Foreign.ForeignPtr.Unsafe+    , module Foreign.Storable+    , module Control.Applicative+    , module Control.Exception+    , module Control.Monad.IO.Class++    , module Data.GI.Base.Attributes+    , module Data.GI.Base.BasicTypes+    , module Data.GI.Base.BasicConversions+    , module Data.GI.Base.Closure+    , module Data.GI.Base.Constructible+    , module Data.GI.Base.GError+    , module Data.GI.Base.GHashTable+    , module Data.GI.Base.GParamSpec+    , module Data.GI.Base.GObject+    , module Data.GI.Base.GVariant+    , module Data.GI.Base.GValue+    , module Data.GI.Base.ManagedPtr+    , module Data.GI.Base.Properties+    , module Data.GI.Base.Signals+    , module Data.GI.Base.Utils++    , module GHC.TypeLits++    , Enum(fromEnum, toEnum)+    , Show(..)+    , Eq(..)+    , IO+    , Monad(..)+    , Maybe(..)+    , (.)+    , ($)+    , (++)+    , (=<<)+    , Bool(..)+    , Float+    , Double+    , undefined+    , error+    , map+    , length+    , mapM+    , mapM_+    , when+    , fromIntegral+    , realToFrac+    ) where++import Control.Monad (when)+import Data.Char (Char, ord, chr)+import Data.Int (Int, Int8, Int16, Int32, Int64)+import Data.Word (Word8, Word16, Word32, Word64)+import Data.ByteString.Char8 (ByteString)+import Foreign.C (CInt(..), CUInt(..), CFloat(..), CDouble(..), CString, CIntPtr(..), CUIntPtr(..), CLong(..), CULong(..))+import Foreign.Ptr (Ptr, plusPtr, FunPtr, nullPtr,+                    castFunPtrToPtr, castPtrToFunPtr)+import Foreign.ForeignPtr (ForeignPtr)+import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)+import Foreign.Storable (peek, poke, sizeOf)+import Control.Applicative ((<$>))+import Control.Exception (onException)+import Control.Monad.IO.Class (MonadIO, liftIO)++import Data.GI.Base.Attributes hiding (get, set)+import Data.GI.Base.BasicTypes+import Data.GI.Base.BasicConversions+import Data.GI.Base.Closure+import Data.GI.Base.Constructible+import Data.GI.Base.GError+import Data.GI.Base.GHashTable+import Data.GI.Base.GObject+import Data.GI.Base.GParamSpec+import Data.GI.Base.GVariant+import Data.GI.Base.GValue+import Data.GI.Base.ManagedPtr+import Data.GI.Base.Properties+import Data.GI.Base.Signals (SignalConnectMode(..), connectSignalFunPtr, SignalHandlerId, SignalInfo(..), GObjectNotifySignalInfo)+import Data.GI.Base.Utils++import GHC.TypeLits (Symbol)
+ Data/GI/Base/Signals.hsc view
@@ -0,0 +1,170 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE UndecidableInstances #-}++-- | Routines for connecting `GObject`s to signals.+module Data.GI.Base.Signals+    ( on+    , after+    , SignalProxy(..)+    , SignalConnectMode(..)+    , connectSignalFunPtr+    , SignalHandlerId+    , SignalInfo(..)+    , GObjectNotifySignalInfo+    ) where++import Control.Monad.IO.Class (MonadIO, liftIO)+import Data.Proxy (Proxy(..))++import Foreign+import Foreign.C++import GHC.TypeLits++import Data.GI.Base.Attributes (AttrLabelProxy, AttrInfo(AttrLabel))+import Data.GI.Base.BasicTypes+import Data.GI.Base.GParamSpec (newGParamSpecFromPtr)+import Data.GI.Base.ManagedPtr (withManagedPtr)+import Data.GI.Base.Overloading (ResolveSignal,+                                 IsLabelProxy(..), ResolveAttribute)+import Data.GI.Base.Utils (safeFreeFunPtrPtr)++#if MIN_VERSION_base(4,9,0)+import GHC.OverloadedLabels (IsLabel(..))+#else+import Data.GI.Base.Overloading (HasSignal)+#endif++-- | Type of a `GObject` signal handler id.+type SignalHandlerId = CULong++-- | A class that provides a constraint satisfied by every type.+class NoConstraint a+instance NoConstraint a++-- | Support for overloaded signal connectors.+data SignalProxy (object :: *) (info :: *) where+    SignalProxy :: SignalProxy o info+    PropertyNotify :: (info ~ ResolveAttribute propName o,+                       AttrInfo info,+                       pl ~ AttrLabel info) =>+                      AttrLabelProxy propName ->+                      SignalProxy o (GObjectNotifySignalInfo pl)++-- | Support for overloaded labels.+instance+#if !MIN_VERSION_base(4,9,0)+    -- This gives better error reporting in ghc < 8.0.+       (HasSignal slot object, info ~ ResolveSignal slot object)+#else+       info ~ ResolveSignal slot object+#endif+    => IsLabelProxy slot (SignalProxy object info) where+    fromLabelProxy _ = SignalProxy++#if MIN_VERSION_base(4,9,0)+instance info ~ ResolveSignal slot object =>+    IsLabel slot (SignalProxy object info) where+    fromLabel _ = SignalProxy+#endif++-- | Information about an overloaded signal.+class SignalInfo (info :: *) where+    type HaskellCallbackType info+    -- | Connect a Haskell function to a signal of the given `GObject`,+    -- specifying whether the handler will be called before or after+    -- the default handler.+    connectSignal :: GObject o =>+                     SignalProxy o info ->+                     o ->+                     HaskellCallbackType info ->+                     SignalConnectMode ->+                     IO SignalHandlerId++-- | Whether to connect a handler to a signal with `connectSignal` so+-- that it runs before/after the default handler for the given signal.+data SignalConnectMode = SignalConnectBefore  -- ^ Run before the default handler.+        | SignalConnectAfter -- ^ Run after the default handler.++-- | Same as `connectSignal`, specifying from the beginning that the+-- handler is to be run before the default handler.+--+-- > on = connectSignal SignalConnectBefore+on :: forall object info m.+      (GObject object, MonadIO m, SignalInfo info) =>+      object -> SignalProxy object info+             -> HaskellCallbackType info -> m SignalHandlerId+on o p c = liftIO $ connectSignal p o c SignalConnectBefore++-- | Connect a signal to a handler, running the handler after the default one.+--+-- > after = connectSignal SignalConnectAfter+after :: forall object info m.+      (GObject object, MonadIO m, SignalInfo info) =>+      object -> SignalProxy object info+             -> HaskellCallbackType info -> m SignalHandlerId+after o p c = liftIO $ connectSignal p o c SignalConnectAfter++-- Connecting GObjects to signals+foreign import ccall "g_signal_connect_data" g_signal_connect_data ::+    Ptr a ->                            -- instance+    CString ->                          -- detailed_signal+    FunPtr b ->                         -- c_handler+    Ptr () ->                           -- data+    FunPtr c ->                         -- destroy_data+    CUInt ->                            -- connect_flags+    IO SignalHandlerId++-- | Connect a signal to a handler, given as a `FunPtr`.+connectSignalFunPtr :: GObject o =>+                  o -> String -> FunPtr a -> SignalConnectMode -> IO SignalHandlerId+connectSignalFunPtr object signal fn mode = do+  let flags = case mode of+                SignalConnectAfter -> 1+                SignalConnectBefore -> 0+  withCString signal $ \csignal ->+    withManagedPtr object $ \objPtr ->+        g_signal_connect_data objPtr csignal fn (castFunPtrToPtr fn) safeFreeFunPtrPtr flags++-- | Connection information for a "notify" signal indicating that a+-- specific property changed (see `PropertyNotify` for the relevant+-- constructor).+data GObjectNotifySignalInfo (propName :: Symbol)+instance KnownSymbol propName =>+    SignalInfo (GObjectNotifySignalInfo propName) where+  type HaskellCallbackType (GObjectNotifySignalInfo propName) = GObjectNotifyCallback+  connectSignal = connectGObjectNotify (symbolVal (Proxy :: Proxy propName))++-- | Type for a `GObject` `notify` callback.+type GObjectNotifyCallback = GParamSpec -> IO ()++gobjectNotifyCallbackWrapper ::+    GObjectNotifyCallback -> Ptr () -> Ptr GParamSpec -> Ptr () -> IO ()+gobjectNotifyCallbackWrapper _cb _ pspec _ = do+    pspec' <- newGParamSpecFromPtr pspec+    _cb  pspec'++type GObjectNotifyCallbackC = Ptr () -> Ptr GParamSpec -> Ptr () -> IO ()++foreign import ccall "wrapper"+    mkGObjectNotifyCallback :: GObjectNotifyCallbackC -> IO (FunPtr GObjectNotifyCallbackC)++-- | Connect the given notify callback for a GObject.+connectGObjectNotify :: forall o i. GObject o =>+                        String ->+                        SignalProxy o (i :: *) ->+                        o -> GObjectNotifyCallback ->+                        SignalConnectMode -> IO SignalHandlerId+connectGObjectNotify propName _ obj cb mode = do+  cb' <- mkGObjectNotifyCallback (gobjectNotifyCallbackWrapper cb)+  let signalName = "notify::" ++ propName+  connectSignalFunPtr obj signalName cb' mode
+ Data/GI/Base/Utils.hsc view
@@ -0,0 +1,200 @@+{-# LANGUAGE ScopedTypeVariables, TupleSections, OverloadedStrings #-}+{- | Assorted utility functions for bindings. -}+module Data.GI.Base.Utils+    ( whenJust+    , maybeM+    , maybeFromPtr+    , mapFirst+    , mapFirstA+    , mapSecond+    , mapSecondA+    , convertIfNonNull+    , convertFunPtrIfNonNull+    , callocBytes+    , callocBoxedBytes+    , callocMem+    , allocBytes+    , allocMem+    , freeMem+    , ptr_to_g_free+    , memcpy+    , safeFreeFunPtr+    , safeFreeFunPtrPtr+    , maybeReleaseFunPtr+    , checkUnexpectedReturnNULL+    , checkUnexpectedNothing+    ) where++#include <glib-object.h>++#if !MIN_VERSION_base(4,8,0)+import Control.Applicative (Applicative, pure, (<$>), (<*>))+#endif+import Control.Exception (throwIO)+import Control.Monad (void)++import qualified Data.Text as T+import Data.Monoid ((<>))+import Data.Word++import Foreign (peek)+import Foreign.C.Types (CSize(..))+import Foreign.Ptr (Ptr, nullPtr, FunPtr, nullFunPtr, freeHaskellFunPtr)+import Foreign.Storable (Storable(..))++import Data.GI.Base.BasicTypes (GType(..), CGType, BoxedObject(..),+                                UnexpectedNullPointerReturn(..))++-- | When the given value is of "Just a" form, execute the given action,+-- otherwise do nothing.+whenJust :: Monad m => Maybe a -> (a -> m ()) -> m ()+whenJust (Just v) f = f v+whenJust Nothing _ = return ()++-- | Like `Control.Monad.maybe`, but for actions on a monad, and with+-- slightly different argument order.+maybeM :: Monad m => b -> Maybe a -> (a -> m b) -> m b+maybeM d Nothing _ = return d+maybeM _ (Just v) action = action v++-- | Check if the pointer is `nullPtr`, and wrap it on a `Maybe`+-- accordingly.+maybeFromPtr :: Ptr a -> Maybe (Ptr a)+maybeFromPtr ptr = if ptr == nullPtr+                   then Nothing+                   else Just ptr++-- | Given a function and a list of two-tuples, apply the function to+-- every first element of the tuples.+mapFirst :: (a -> c) -> [(a,b)] -> [(c,b)]+mapFirst _ [] = []+mapFirst f ((x,y) : rest) = (f x, y) : mapFirst f rest++-- | Same for the second element.+mapSecond :: (b -> c) -> [(a,b)] -> [(a,c)]+mapSecond _ [] = []+mapSecond f ((x,y) : rest) = (x, f y) : mapSecond f rest++-- | Applicative version of `mapFirst`.+mapFirstA :: Applicative f => (a -> f c) -> [(a,b)] -> f [(c,b)]+mapFirstA _ [] = pure []+mapFirstA f ((x,y) : rest) = (:) <$> ((,y) <$> f x) <*> mapFirstA f rest++-- | Applicative version of `mapSecond`.+mapSecondA :: Applicative f => (b -> f c) -> [(a,b)] -> f [(a,c)]+mapSecondA _ [] = pure []+mapSecondA f ((x,y) : rest) = (:) <$> ((x,) <$> f y) <*> mapSecondA f rest++-- | Apply the given conversion action to the given pointer if it is+-- non-NULL, otherwise return `Nothing`.+convertIfNonNull :: Ptr a -> (Ptr a -> IO b) -> IO (Maybe b)+convertIfNonNull ptr convert = if ptr == nullPtr+                               then return Nothing+                               else Just <$> convert ptr++-- | Apply the given conversion action to the given function pointer+-- if it is non-NULL, otherwise return `Nothing`.+convertFunPtrIfNonNull :: FunPtr a -> (FunPtr a -> IO b) -> IO (Maybe b)+convertFunPtrIfNonNull ptr convert = if ptr == nullFunPtr+                                     then return Nothing+                                     else Just <$> convert ptr++foreign import ccall "g_malloc0" g_malloc0 ::+    #{type gsize} -> IO (Ptr a)++-- | Make a zero-filled allocation using the GLib allocator.+{-# INLINE callocBytes #-}+callocBytes :: Int -> IO (Ptr a)+callocBytes n =  g_malloc0 (fromIntegral n)++-- | Make a zero-filled allocation of enough size to hold the given+-- `Storable` type, using the GLib allocator.+{-# INLINE callocMem #-}+callocMem :: forall a. Storable a => IO (Ptr a)+callocMem = g_malloc0 $ (fromIntegral . sizeOf) (undefined :: a)++foreign import ccall "g_boxed_copy" g_boxed_copy ::+    CGType -> Ptr a -> IO (Ptr a)++-- | Make a zero filled allocation of n bytes for a boxed object. The+-- difference with a normal callocBytes is that the returned memory is+-- allocated using whatever memory allocator g_boxed_copy uses, which+-- in particular may well be different from a plain g_malloc. In+-- particular g_slice_alloc is often used for allocating boxed+-- objects, which are then freed using g_slice_free.+callocBoxedBytes :: forall a. BoxedObject a => Int -> IO (Ptr a)+callocBoxedBytes n = do+  ptr <- callocBytes n+  GType cgtype <- boxedType (undefined :: a)+  result <- g_boxed_copy cgtype ptr+  freeMem ptr+  return result++foreign import ccall "g_malloc" g_malloc ::+    #{type gsize} -> IO (Ptr a)++-- | Allocate the given number of bytes using the GLib allocator.+{-# INLINE allocBytes #-}+allocBytes :: Integral a => a -> IO (Ptr b)+allocBytes n = g_malloc (fromIntegral n)++-- | Allocate space for the given `Storable` using the GLib allocator.+{-# INLINE allocMem #-}+allocMem :: forall a. Storable a => IO (Ptr a)+allocMem = g_malloc $ (fromIntegral . sizeOf) (undefined :: a)++-- | A wrapper for `g_free`.+foreign import ccall "g_free" freeMem :: Ptr a -> IO ()++-- | Pointer to `g_free`.+foreign import ccall "&g_free" ptr_to_g_free :: FunPtr (Ptr a -> IO ())++foreign import ccall unsafe "string.h memcpy" _memcpy :: Ptr a -> Ptr b -> CSize -> IO (Ptr ())++-- | Copy memory into a destination (in the first argument) from a+-- source (in the second argument).+{-# INLINE memcpy #-}+memcpy :: Ptr a -> Ptr b -> Int -> IO ()+memcpy dest src n = void $ _memcpy dest src (fromIntegral n)++-- | Same as freeHaskellFunPtr, but it does nothing when given a+-- nullPtr.+foreign import ccall "safeFreeFunPtr" safeFreeFunPtr ::+    Ptr a -> IO ()++-- | A pointer to `safeFreeFunPtr`.+foreign import ccall "& safeFreeFunPtr" safeFreeFunPtrPtr ::+    FunPtr (Ptr a -> IO ())++-- | If given a pointer to the memory location, free the `FunPtr` at+-- that location, and then the pointer itself. Useful for freeing the+-- memory associated to callbacks which are called just once, with no+-- destroy notification.+maybeReleaseFunPtr :: Maybe (Ptr (FunPtr a)) -> IO ()+maybeReleaseFunPtr Nothing = return ()+maybeReleaseFunPtr (Just f) = do+  peek f >>= freeHaskellFunPtr+  freeMem f++-- | Check that the given pointer is not NULL. If it is, raise a+-- `UnexpectedNullPointerReturn` exception.+checkUnexpectedReturnNULL :: T.Text -> Ptr a -> IO ()+checkUnexpectedReturnNULL fnName ptr+    | ptr == nullPtr =+        throwIO (UnexpectedNullPointerReturn {+                   nullPtrErrorMsg = "Received unexpected nullPtr in \""+                                     <> fnName <> "\"."+                 })+    | otherwise = return ()++-- | An annotated version of `fromJust`, which raises a+-- `UnexpectedNullPointerReturn` in case it encounters a `Nothing`.+checkUnexpectedNothing :: T.Text -> IO (Maybe a) -> IO a+checkUnexpectedNothing fnName action = do+  result <- action+  case result of+    Just r -> return r+    Nothing -> throwIO (UnexpectedNullPointerReturn {+                 nullPtrErrorMsg = "Received unexpected nullPtr in \""+                                     <> fnName <> "\"."+                 })
+ c/hsgclosure.c view
@@ -0,0 +1,106 @@+#define _GNU_SOURCE++/* GHC's semi-public Rts API */+#include <Rts.h>++#include <stdlib.h>++#include <glib-object.h>++int check_object_type(void *instance, GType type)+{+  int result;++  if (instance != NULL) {+     result = !!G_TYPE_CHECK_INSTANCE_TYPE(instance, type);+  } else {+    result = 0;+    fprintf(stderr, "Check failed: got a null pointer\n");+  }++  return result;+}++static int print_debug_info ()+{+  static int __print_debug_info = -1;++  if (__print_debug_info == -1) {+    __print_debug_info = getenv ("HASKELL_GI_DEBUG_MEM") != NULL;+  }++  return __print_debug_info;+}++/* Auxiliary function for freeing boxed types */+void boxed_free_helper (GType gtype, void *boxed)+{+  if (print_debug_info()) {+    fprintf(stderr, "Freeing a boxed object at %p\n", boxed);+    fprintf(stderr, "\tIt is of type %s\n", g_type_name(gtype));+  }++  g_boxed_free (gtype, boxed);++  if (print_debug_info()) {+    fprintf(stderr, "\tdone\n");+  }+}++void dbg_g_object_disown (GObject *obj)+{+  GType gtype;++  if (print_debug_info()) {+    fprintf(stderr, "Disowning a GObject at %p\n", obj);+    gtype = G_TYPE_FROM_INSTANCE (obj);+    fprintf(stderr, "\tIt is of type %s\n", g_type_name(gtype));+    fprintf(stderr, "\tIts refcount before disowning is %d\n",+            (int)obj->ref_count);+  }+}++void dbg_g_object_unref (GObject *obj)+{+  GType gtype;++  if (print_debug_info()) {+    fprintf(stderr, "Freeing a GObject at %p\n", obj);+    gtype = G_TYPE_FROM_INSTANCE (obj);+    fprintf(stderr, "\tIt is of type %s\n", g_type_name(gtype));+    fprintf(stderr, "\tIts refcount before unref is %d\n",+            (int)obj->ref_count);+  }++  g_object_unref(obj);++  if (print_debug_info()) {+    fprintf(stderr, "\tdone\n");+  }+}++gpointer dbg_g_object_newv (GType gtype, guint n_params, GParameter *params)+{+  gpointer result;++  if (print_debug_info()) {+    fprintf(stderr, "Creating a new GObject of type %s\n",+            g_type_name(gtype));+  }++  result = g_object_newv (gtype, n_params, params);++  if (print_debug_info()) {+    fprintf(stderr, "\tdone, got a pointer at %p\n", result);+  }++  return result;+}++/* Same as freeHaskellFunctionPtr, but it does nothing when given a+   null pointer, instead of crashing */+void safeFreeFunPtr(void *ptr)+{+  if (ptr != NULL)+    freeHaskellFunctionPtr(ptr);+}
haskell-gi-base.cabal view
@@ -1,5 +1,5 @@ name:                haskell-gi-base-version:             0.19+version:             0.20 synopsis:            Foundation for libraries generated by haskell-gi description:         Foundation for libraries generated by haskell-gi homepage:            https://github.com/haskell-gi/haskell-gi-base@@ -20,7 +20,6 @@   location: git://github.com/haskell-gi/haskell-gi-base.git  library-  hs-source-dirs:      src   exposed-modules:     Data.GI.Base,                        Data.GI.Base.Attributes,                        Data.GI.Base.BasicConversions,@@ -56,5 +55,6 @@     ghc-options: -Wall -fwarn-incomplete-patterns    build-tools:         hsc2hs+  cc-options:          -fPIC   extensions:          CPP, ForeignFunctionInterface, DoAndIfThenElse-  c-sources:           src/c/hsgclosure.c+  c-sources:           c/hsgclosure.c
− src/Data/GI/Base.hs
@@ -1,33 +0,0 @@-{- |-   == Convenience header for basic GObject-Introspection modules--See the documentation for each individual module for a description and-usage help.--}-module Data.GI.Base-    ( module Data.GI.Base.Attributes-    , module Data.GI.Base.BasicConversions-    , module Data.GI.Base.BasicTypes-    , module Data.GI.Base.Closure-    , module Data.GI.Base.Constructible-    , module Data.GI.Base.GError-    , module Data.GI.Base.GHashTable-    , module Data.GI.Base.GObject-    , module Data.GI.Base.GValue-    , module Data.GI.Base.GVariant-    , module Data.GI.Base.ManagedPtr-    , module Data.GI.Base.Signals-    ) where--import Data.GI.Base.Attributes (get, set, AttrOp(..))-import Data.GI.Base.BasicConversions-import Data.GI.Base.BasicTypes-import Data.GI.Base.Closure-import Data.GI.Base.Constructible (new)-import Data.GI.Base.GError-import Data.GI.Base.GHashTable-import Data.GI.Base.GObject (new')-import Data.GI.Base.GValue (GValue(..), IsGValue(..))-import Data.GI.Base.GVariant-import Data.GI.Base.ManagedPtr-import Data.GI.Base.Signals (on, after, SignalProxy(PropertyNotify))
− src/Data/GI/Base/Attributes.hs
@@ -1,364 +0,0 @@-{-# LANGUAGE GADTs, ScopedTypeVariables, DataKinds, KindSignatures,-  TypeFamilies, TypeOperators, MultiParamTypeClasses, ConstraintKinds,-  UndecidableInstances, FlexibleInstances #-}---- |------ == Basic attributes interface------ Attributes of an object can be get, set and constructed. For types--- descending from 'Data.GI.Base.BasicTypes.GObject', properties are--- encoded in attributes, although attributes are slightly more--- general (every property of a `Data.GI.Base.BasicTypes.GObject` is an--- attribute, but we can also have attributes for types not descending--- from `Data.GI.Base.BasicTypes.GObject`).------ As an example consider a @button@ widget and a property (of the--- Button class, or any of its parent classes or implemented--- interfaces) called "label". The simplest way of getting the value--- of the button is to do------ > value <- getButtonLabel button------ And for setting:------ > setButtonLabel button label------ This mechanism quickly becomes rather cumbersome, for example for--- setting the "window" property in a DOMDOMWindow in WebKit:------ > win <- getDOMDOMWindowWindow dom------ and perhaps more importantly, one needs to chase down the type--- which introduces the property:------ > setWidgetSensitive button False------ There is no @setButtonSensitive@, since it is the @Widget@ type--- that introduces the "sensitive" property.------ == Overloaded attributes------ A much more convenient overloaded attribute resolution API is--- provided by this module. Getting the value of an object's attribute--- is straightforward:------ > value <- get button _label------ The definition of @_label@ is basically a 'Proxy' encoding the name--- of the attribute to get:------ > _label = fromLabelProxy (Proxy :: Proxy "label")------ These proxies can be automatically generated by invoking the code--- generator with the @-l@ option. The leading underscore is simply so--- the autogenerated identifiers do not pollute the namespace, but if--- this is not a concern the autogenerated names (in the autogenerated--- @GI/Properties.hs@) can be edited as one wishes.------ In addition, for ghc >= 8.0, one can directly use the overloaded--- labels provided by GHC itself. Using the "OverloadedLabels"--- extension, the code above can also be written as------ > value <- get button #label------ The syntax for setting or updating an attribute is only slightly more--- complex. At the simplest level it is just:------ > set button [ _label := value ]------ or for the WebKit example above------ > set dom [_window := win]------ However as the list notation would indicate, you can set or update multiple--- attributes of the same object in one go:------ > set button [ _label := value, _sensitive := False ]------ You are not limited to setting the value of an attribute, you can also--- apply an update function to an attribute's value. That is the function--- receives the current value of the attribute and returns the new value.------ > set spinButton [ _value :~ (+1) ]------ There are other variants of these operators, see 'AttrOp'--- below. ':=>' and ':~>' are like ':=' and ':~' but operate in the--- 'IO' monad rather than being pure. There is also '::=' and '::~'--- which take the object as an extra parameter.------ Attributes can also be set during construction of a--- `Data.GI.Base.BasicTypes.GObject` using `Data.GI.Base.Properties.new`------ > button <- new Button [_label := "Can't touch this!", _sensitive := False]------ In addition for value being set/get having to have the right type,--- there can be attributes that are read-only, or that can only be set--- during construction with `Data.GI.Base.Properties.new`, but cannot be--- `set` afterwards. That these invariants hold is also checked during--- compile time.------ == Nullable atributes------ Whenever the attribute is represented as a pointer in the C side,--- it is often the case that the underlying C representation admits or--- returns @NULL@ as a valid value for the property. In these cases--- the `get` operation may return a `Maybe` value, with `Nothing`--- representing the @NULL@ pointer value (notable exceptions are--- `Data.GI.Base.BasicTypes.GList` and--- `Data.GI.Base.BasicTypes.GSList`, for which @NULL@ is represented--- simply as he empty list). This can be overriden in the--- introspection data, since sometimes attributes are non-nullable,--- even if the type would allow for @NULL@.------ For convenience, in nullable cases the `set` operation will by--- default /not/ take a `Maybe` value, but rather assume that the--- caller wants to set a non-@NULL@ value. If setting a @NULL@ value--- is desired, use `clear` as follows------ > clear object _propName----module Data.GI.Base.Attributes (-  AttrInfo(..),--  AttrOpTag(..),--  AttrOp(..),-  AttrOpAllowed,--  AttrGetC,-  AttrSetC,-  AttrConstructC,-  AttrClearC,--  get,-  set,-  clear,--  AttrLabelProxy(..)-  ) where--import Control.Monad.IO.Class (MonadIO, liftIO)--import Data.Proxy (Proxy(..))--import Data.GI.Base.GValue (GValueConstruct)-import Data.GI.Base.Overloading (HasAttributeList,-                                 ResolveAttribute, IsLabelProxy(..))--import GHC.TypeLits-import GHC.Exts (Constraint)--#if MIN_VERSION_base(4,9,0)-import GHC.OverloadedLabels (IsLabel(..))-#endif--infixr 0 :=,:~,:=>,:~>,::=,::~---- | A proxy for attribute labels.-data AttrLabelProxy (a :: Symbol) = AttrLabelProxy---- | Support for overloaded labels.-instance a ~ x => IsLabelProxy x (AttrLabelProxy a) where-    fromLabelProxy _ = AttrLabelProxy--#if MIN_VERSION_base(4,9,0)-instance a ~ x => IsLabel x (AttrLabelProxy a) where-    fromLabel _ = AttrLabelProxy-#endif---- | Info describing an attribute.-class AttrInfo (info :: *) where-    -- | The operations that are allowed on the attribute.-    type AttrAllowedOps info :: [AttrOpTag]-    -- | Constraint on the value being set.-    type AttrSetTypeConstraint info :: * -> Constraint-    -- | Constraint on the type for which we are allowed to-    -- create\/set\/get the attribute.-    type AttrBaseTypeConstraint info :: * -> Constraint-    -- | Type returned by `attrGet`.-    type AttrGetType info-    -- | A string describing the attribute (for error messages).-    type AttrLabel info :: Symbol-    -- | Get the value of the given attribute.-    attrGet :: AttrBaseTypeConstraint info o =>-               Proxy info -> o -> IO (AttrGetType info)-    -- | Set the value of the given attribute, after the object having-    -- the attribute has already been created.-    attrSet :: (AttrBaseTypeConstraint info o,-                AttrSetTypeConstraint info b) =>-               Proxy info -> o -> b -> IO ()-    -- | Set the value of the given attribute to @NULL@ (for nullable-    -- attributes).-    attrClear :: AttrBaseTypeConstraint info o =>-                 Proxy info -> o -> IO ()-    -- | Build a `GValue` representing the attribute.-    attrConstruct :: (AttrBaseTypeConstraint info o,-                      AttrSetTypeConstraint info b) =>-                     Proxy info -> b -> IO (GValueConstruct o)---- | Result of checking whether an op is allowed on an attribute.-data OpAllowed tag attrName =-    OpIsAllowed-#if !MIN_VERSION_base(4,9,0)-        | AttrOpNotAllowed Symbol tag Symbol attrName-#endif---- | Look in the given list to see if the given `AttrOp` is a member,--- if not return an error type.-type family AttrOpIsAllowed (tag :: AttrOpTag) (ops :: [AttrOpTag]) (label :: Symbol) :: OpAllowed AttrOpTag Symbol where-    AttrOpIsAllowed tag '[] label =-#if !MIN_VERSION_base(4,9,0)-        'AttrOpNotAllowed "Error: operation " tag " not allowed for attribute type " label-#else-        TypeError ('Text "Attribute ‘" ':<>: 'Text label ':<>:-                   'Text "’ is not " ':<>:-                   'Text (AttrOpText tag) ':<>: 'Text ".")-#endif-    AttrOpIsAllowed tag (tag ': ops) label = 'OpIsAllowed-    AttrOpIsAllowed tag (other ': ops) label = AttrOpIsAllowed tag ops label---- | Whether a given `AttrOpTag` is allowed on an attribute, given the--- info type.-type family AttrOpAllowed (tag :: AttrOpTag) (info :: *) :: Constraint where-    AttrOpAllowed tag info =-        AttrOpIsAllowed tag (AttrAllowedOps info) (AttrLabel info) ~ 'OpIsAllowed---- | Possible operations on an attribute.-data AttrOpTag = AttrGet | AttrSet | AttrConstruct | AttrClear--#if MIN_VERSION_base(4,9,0)--- | A user friendly description of the `AttrOpTag`, useful when--- printing type errors.-type family AttrOpText (tag :: AttrOpTag) :: Symbol where-    AttrOpText 'AttrGet = "gettable"-    AttrOpText 'AttrSet = "settable"-    AttrOpText 'AttrConstruct = "constructible"-    AttrOpText 'AttrClear = "nullable"-#endif---- | Constraint on a @obj@\/@attr@ pair so that `set` works on values--- of type @value@.-type AttrSetC info obj attr value = (HasAttributeList obj,-                                     info ~ ResolveAttribute attr obj,-                                     AttrInfo info,-                                     AttrBaseTypeConstraint info obj,-                                     AttrOpAllowed 'AttrSet info,-                                     (AttrSetTypeConstraint info) value)---- | Constraint on a @obj@\/@value@ pair so that `new` works on values--- of type @@value@.-type AttrConstructC info obj attr value = (HasAttributeList obj,-                                           info ~ ResolveAttribute attr obj,-                                           AttrInfo info,-                                           AttrBaseTypeConstraint info obj,-                                           AttrOpAllowed 'AttrConstruct info,-                                           (AttrSetTypeConstraint info) value)---- | Constructors for the different operations allowed on an attribute.-data AttrOp obj (tag :: AttrOpTag) where-    -- Assign a value to an attribute-    (:=)  :: (HasAttributeList obj,-              info ~ ResolveAttribute attr obj,-              AttrInfo info,-              AttrBaseTypeConstraint info obj,-              AttrOpAllowed tag info,-              (AttrSetTypeConstraint info) b) =>-             AttrLabelProxy (attr :: Symbol) -> b -> AttrOp obj tag-    -- Assign the result of an IO action to an attribute-    (:=>) :: (HasAttributeList obj,-              info ~ ResolveAttribute attr obj,-              AttrInfo info,-              AttrBaseTypeConstraint info obj,-              AttrOpAllowed tag info,-              (AttrSetTypeConstraint info) b) =>-             AttrLabelProxy (attr :: Symbol) -> IO b -> AttrOp obj tag-    -- Apply an update function to an attribute-    (:~)  :: (HasAttributeList obj,-              info ~ ResolveAttribute attr obj,-              AttrInfo info,-              AttrBaseTypeConstraint info obj,-              tag ~ 'AttrSet,-              AttrOpAllowed 'AttrSet info,-              AttrOpAllowed 'AttrGet info,-              (AttrSetTypeConstraint info) b,-              a ~ (AttrGetType info)) =>-             AttrLabelProxy (attr :: Symbol) -> (a -> b) -> AttrOp obj tag-    -- Apply an IO update function to an attribute-    (:~>) :: (HasAttributeList obj,-              info ~ ResolveAttribute attr obj,-              AttrInfo info,-              AttrBaseTypeConstraint info obj,-              tag ~ 'AttrSet,-              AttrOpAllowed 'AttrSet info,-              AttrOpAllowed 'AttrGet info,-              (AttrSetTypeConstraint info) b,-              a ~ (AttrGetType info)) =>-             AttrLabelProxy (attr :: Symbol) -> (a -> IO b) -> AttrOp obj tag-    -- Assign a value to an attribute with the object as an argument-    (::=) :: (HasAttributeList obj,-              info ~ ResolveAttribute attr obj,-              AttrInfo info,-              AttrBaseTypeConstraint info obj,-              tag ~ 'AttrSet,-              AttrOpAllowed tag info,-              (AttrSetTypeConstraint info) b) =>-             AttrLabelProxy (attr :: Symbol) -> (obj -> b) -> AttrOp obj tag-    -- Apply an update function to an attribute with the object as an-    -- argument-    (::~) :: (HasAttributeList obj,-              info ~ ResolveAttribute attr obj,-              AttrInfo info,-              AttrBaseTypeConstraint info obj,-              tag ~ 'AttrSet,-              AttrOpAllowed 'AttrSet info,-              AttrOpAllowed 'AttrGet info,-              (AttrSetTypeConstraint info) b,-              a ~ (AttrGetType info)) =>-             AttrLabelProxy (attr :: Symbol) -> (obj -> a -> b) -> AttrOp obj tag---- | Set a number of properties for some object.-set :: forall o m. MonadIO m => o -> [AttrOp o 'AttrSet] -> m ()-set obj = liftIO . mapM_ app- where-   resolve :: AttrLabelProxy attr -> Proxy (ResolveAttribute attr o)-   resolve _ = Proxy--   app :: AttrOp o 'AttrSet -> IO ()-   app (attr :=  x) = attrSet (resolve attr) obj x-   app (attr :=> x) = x >>= attrSet (resolve attr) obj-   app (attr :~  f) = attrGet (resolve attr) obj >>=-                      \v -> attrSet (resolve attr) obj (f v)-   app (attr :~> f) = attrGet (resolve attr) obj >>= f >>=-                      attrSet (resolve attr) obj-   app (attr ::= f) = attrSet (resolve attr) obj (f obj)-   app (attr ::~ f) = attrGet (resolve attr) obj >>=-                      \v -> attrSet (resolve attr) obj (f obj v)---- | Constraints on a @obj@\/@attr@ pair so `get` is possible,--- producing a value of type @result@.-type AttrGetC info obj attr result = (HasAttributeList obj,-                                      info ~ ResolveAttribute attr obj,-                                      AttrInfo info,-                                      (AttrBaseTypeConstraint info) obj,-                                      AttrOpAllowed 'AttrGet info,-                                      result ~ AttrGetType info)---- | Get the value of an attribute for an object.-get :: forall info attr obj result m.-       (AttrGetC info obj attr result, MonadIO m) =>-        obj -> AttrLabelProxy (attr :: Symbol) -> m result-get o _ = liftIO $ attrGet (Proxy :: Proxy info) o---- | Constraint on a @obj@\/@attr@ pair so that `clear` is allowed.-type AttrClearC info obj attr = (HasAttributeList obj,-                                 info ~ ResolveAttribute attr obj,-                                 AttrInfo info,-                                 (AttrBaseTypeConstraint info) obj,-                                 AttrOpAllowed 'AttrClear info)---- | Set a nullable attribute to @NULL@.-clear :: forall info attr obj m.-         (AttrClearC info obj attr, MonadIO m) =>-         obj -> AttrLabelProxy (attr :: Symbol) -> m ()-clear o _ = liftIO $ attrClear (Proxy :: Proxy info) o
− src/Data/GI/Base/BasicConversions.hsc
@@ -1,595 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# OPTIONS_GHC -fno-warn-name-shadowing #-}-module Data.GI.Base.BasicConversions-    ( gflagsToWord-    , wordToGFlags--    , packGList-    , unpackGList-    , packGSList-    , unpackGSList-    , packGArray-    , unpackGArray-    , unrefGArray-    , packGPtrArray-    , unpackGPtrArray-    , unrefPtrArray-    , packGByteArray-    , unpackGByteArray-    , unrefGByteArray-    , packGHashTable-    , unpackGHashTable-    , unrefGHashTable-    , packByteString-    , packZeroTerminatedByteString-    , unpackByteStringWithLength-    , unpackZeroTerminatedByteString-    , packFileNameArray-    , packZeroTerminatedFileNameArray-    , unpackZeroTerminatedFileNameArray-    , unpackFileNameArrayWithLength-    , packUTF8CArray-    , packZeroTerminatedUTF8CArray-    , unpackUTF8CArrayWithLength-    , unpackZeroTerminatedUTF8CArray-    , packStorableArray-    , packZeroTerminatedStorableArray-    , unpackStorableArrayWithLength-    , unpackZeroTerminatedStorableArray-    , packMapStorableArray-    , packMapZeroTerminatedStorableArray-    , unpackMapStorableArrayWithLength-    , unpackMapZeroTerminatedStorableArray-    , packPtrArray-    , packZeroTerminatedPtrArray-    , unpackPtrArrayWithLength-    , unpackZeroTerminatedPtrArray-    , packBlockArray-    , unpackBlockArrayWithLength-    , unpackBoxedArrayWithLength--    , stringToCString-    , cstringToString-    , textToCString-    , withTextCString-    , cstringToText-    , byteStringToCString-    , cstringToByteString--    , mapZeroTerminatedCArray-    , mapCArrayWithLength-    , mapGArray-    , mapPtrArray-    , mapGList-    , mapGSList-    ) where--#if !MIN_VERSION_base(4,8,0)-import Control.Applicative ((<$>), (<*>))-#endif-import Control.Exception.Base (bracket)-import Control.Monad (foldM)--import Data.ByteString (ByteString)-import qualified Data.ByteString as B-import qualified Data.ByteString.Internal as BI-import Data.Maybe (fromMaybe)-import Data.Text (Text)-import qualified Data.Text.Foreign as TF--import Foreign.Ptr (Ptr, plusPtr, nullPtr, nullFunPtr, castPtr)-import Foreign.ForeignPtr (withForeignPtr)-import Foreign.Storable (Storable, peek, poke, sizeOf)-import Foreign.C.Types (CInt(..), CUInt(..), CSize(..), CChar(..))-import Foreign.C.String (CString, withCString, peekCString)-import Data.Word-import Data.Int (Int32)-import Data.Bits (Bits, (.|.), (.&.), shift)--import Data.GI.Base.BasicTypes-import Data.GI.Base.GHashTable (GEqualFunc, GHashFunc)-import Data.GI.Base.ManagedPtr (copyBoxedPtr)-import Data.GI.Base.Utils (allocBytes, callocBytes, memcpy, freeMem)--#include <glib-object.h>--gflagsToWord :: (Num b, IsGFlag a) => [a] -> b-gflagsToWord flags = fromIntegral (go flags)-    where go (f:fs) = fromEnum f .|. go fs-          go [] = 0--wordToGFlags :: (Storable a, Integral a, Bits a, IsGFlag b) => a -> [b]-wordToGFlags w = go 0-    where-      nbits = (sizeOf w)*8-      go k-          | k == nbits = []-          | otherwise = if mask .&. w /= 0-                        then toEnum (fromIntegral mask) : go (k+1)-                        else go (k+1)-          where mask = shift 1 k--foreign import ccall "g_list_prepend" g_list_prepend ::-    Ptr (GList (Ptr a)) -> Ptr a -> IO (Ptr (GList (Ptr a)))---- Given a Haskell list of items, construct a GList with those values.-packGList   :: [Ptr a] -> IO (Ptr (GList (Ptr a)))-packGList l = foldM g_list_prepend nullPtr $ reverse l---- Given a GSList construct the corresponding Haskell list.-unpackGList   :: Ptr (GList (Ptr a)) -> IO [Ptr a]-unpackGList gsl-    | gsl == nullPtr = return []-    | otherwise =-        do x <- peek (castPtr gsl)-           next <- peek (gsl `plusPtr` sizeOf x)-           xs <- unpackGList next-           return $ x : xs---- Same thing for singly linked lists--foreign import ccall "g_slist_prepend" g_slist_prepend ::-    Ptr (GSList (Ptr a)) -> Ptr a -> IO (Ptr (GSList (Ptr a)))---- Given a Haskell list of items, construct a GSList with those values.-packGSList   :: [Ptr a] -> IO (Ptr (GSList (Ptr a)))-packGSList l = foldM g_slist_prepend nullPtr $ reverse l---- Given a GSList construct the corresponding Haskell list.-unpackGSList   :: Ptr (GSList (Ptr a)) -> IO [Ptr a]-unpackGSList gsl = unpackGList (castPtr gsl)--foreign import ccall "g_array_new" g_array_new ::-   CInt -> CInt -> CUInt -> IO (Ptr (GArray ()))-foreign import ccall "g_array_set_size" g_array_set_size ::-    Ptr (GArray ()) -> CUInt -> IO (Ptr (GArray ()))-foreign import ccall "g_array_unref" unrefGArray ::-   Ptr (GArray a) -> IO ()--packGArray :: forall a. Storable a => [a] -> IO (Ptr (GArray a))-packGArray elems = do-  let elemsize = sizeOf (elems!!0)-  array <- g_array_new 0 0 (fromIntegral elemsize)-  _ <- g_array_set_size array (fromIntegral $ length elems)-  dataPtr <- peek (castPtr array :: Ptr (Ptr a))-  fill dataPtr elems-  return $ castPtr array-  where-    fill            :: Ptr a -> [a] -> IO ()-    fill _ []       = return ()-    fill ptr (x:xs) =-        do poke ptr x-           fill (ptr `plusPtr` (sizeOf x)) xs--unpackGArray :: forall a. Storable a => Ptr (GArray a) -> IO [a]-unpackGArray array = do-  dataPtr <- peek (castPtr array :: Ptr (Ptr a))-  nitems <- peek (array `plusPtr` sizeOf dataPtr)-  go dataPtr nitems-    where go :: Ptr a -> Int -> IO [a]-          go _ 0 = return []-          go ptr n = do-            x <- peek ptr-            (x:) <$> go (ptr `plusPtr` sizeOf x) (n-1)--foreign import ccall "g_ptr_array_new" g_ptr_array_new ::-    IO (Ptr (GPtrArray ()))-foreign import ccall "g_ptr_array_set_size" g_ptr_array_set_size ::-    Ptr (GPtrArray ()) -> CUInt -> IO (Ptr (GPtrArray ()))-foreign import ccall "g_ptr_array_unref" unrefPtrArray ::-   Ptr (GPtrArray a) -> IO ()--packGPtrArray :: [Ptr a] -> IO (Ptr (GPtrArray (Ptr a)))-packGPtrArray elems = do-  array <- g_ptr_array_new-  _ <- g_ptr_array_set_size array (fromIntegral $ length elems)-  dataPtr <- peek (castPtr array :: Ptr (Ptr (Ptr a)))-  fill dataPtr elems-  return $ castPtr array-  where-    fill            :: Ptr (Ptr a) -> [Ptr a] -> IO ()-    fill _ []       = return ()-    fill ptr (x:xs) =-        do poke ptr x-           fill (ptr `plusPtr` (sizeOf x)) xs--unpackGPtrArray :: Ptr (GPtrArray (Ptr a)) -> IO [Ptr a]-unpackGPtrArray array = do-  dataPtr <- peek (castPtr array :: Ptr (Ptr (Ptr a)))-  nitems <- peek (array `plusPtr` sizeOf dataPtr)-  go dataPtr nitems-    where go :: Ptr (Ptr a) -> Int -> IO [Ptr a]-          go _ 0 = return []-          go ptr n = do-            x <- peek ptr-            (x:) <$> go (ptr `plusPtr` sizeOf x) (n-1)--foreign import ccall "g_byte_array_new" g_byte_array_new ::-    IO (Ptr GByteArray)-foreign import ccall "g_byte_array_append" g_byte_array_append ::-    Ptr GByteArray -> Ptr a -> CUInt -> IO (Ptr GByteArray)-foreign import ccall "g_byte_array_unref" unrefGByteArray ::-   Ptr GByteArray -> IO ()--packGByteArray :: ByteString -> IO (Ptr GByteArray)-packGByteArray bs = do-  array <- g_byte_array_new-  let (ptr, offset, length) = BI.toForeignPtr bs-  _ <- withForeignPtr ptr $ \dataPtr ->-                    g_byte_array_append array (dataPtr `plusPtr` offset)-                                        (fromIntegral length)-  return array--unpackGByteArray :: Ptr GByteArray -> IO ByteString-unpackGByteArray array = do-  dataPtr <- peek (castPtr array :: Ptr (Ptr CChar))-  length <- peek (array `plusPtr` (sizeOf dataPtr)) :: IO CUInt-  B.packCStringLen (dataPtr, fromIntegral length)--foreign import ccall "g_hash_table_new_full" g_hash_table_new_full ::-    GHashFunc a -> GEqualFunc a -> GDestroyNotify a -> GDestroyNotify b ->-                 IO (Ptr (GHashTable a b))-foreign import ccall "g_hash_table_insert" g_hash_table_insert ::-    Ptr (GHashTable a b) -> PtrWrapped a -> PtrWrapped b -> IO #{type gboolean}--packGHashTable :: GHashFunc a -> GEqualFunc a ->-                  Maybe (GDestroyNotify a) -> Maybe (GDestroyNotify b) ->-                  [(PtrWrapped a, PtrWrapped b)] -> IO (Ptr (GHashTable a b))-packGHashTable keyHash keyEqual keyDestroy elemDestroy pairs = do-  let keyDPtr = fromMaybe nullFunPtr keyDestroy-      elemDPtr = fromMaybe nullFunPtr elemDestroy-  ht <- g_hash_table_new_full keyHash keyEqual keyDPtr elemDPtr-  mapM_ (uncurry (g_hash_table_insert ht)) pairs-  return ht--foreign import ccall "g_hash_table_get_keys" g_hash_table_get_keys ::-    Ptr (GHashTable a b) -> IO (Ptr (GList (Ptr a)))-foreign import ccall "g_hash_table_lookup" g_hash_table_lookup ::-    Ptr (GHashTable a b) -> PtrWrapped a -> IO (PtrWrapped b)-unpackGHashTable :: Ptr (GHashTable a b) -> IO [(PtrWrapped a, PtrWrapped b)]-unpackGHashTable ht = do-  keysGList <- g_hash_table_get_keys ht-  keys <- (map (PtrWrapped . castPtr)) <$> unpackGList keysGList-  g_list_free keysGList-  -- At this point we could use g_hash_table_get_values, since the-  -- current implementation in GLib returns elements in the same order-  -- as g_hash_table_get_keys. But to be on the safe side, since the-  -- ordering is not specified in the documentation, we do the-  -- following, which is (quite) slower but manifestly safe.-  elems <- mapM (g_hash_table_lookup ht) keys-  return (zip keys elems)--foreign import ccall "g_hash_table_unref" unrefGHashTable ::-   Ptr (GHashTable a b) -> IO ()--packByteString :: ByteString -> IO (Ptr Word8)-packByteString bs = do-  let (ptr, offset, length) = BI.toForeignPtr bs-  mem <- allocBytes length-  withForeignPtr ptr $ \dataPtr ->-      memcpy mem (dataPtr `plusPtr` offset) (fromIntegral length)-  return mem--packZeroTerminatedByteString :: ByteString -> IO (Ptr Word8)-packZeroTerminatedByteString bs = do-  let (ptr, offset, length) = BI.toForeignPtr bs-  mem <- allocBytes (length+1)-  withForeignPtr ptr $ \dataPtr ->-      memcpy mem (dataPtr `plusPtr` offset) (fromIntegral length)-  poke (mem `plusPtr` (offset+length)) (0 :: Word8)-  return mem--unpackByteStringWithLength :: Integral a => a -> Ptr Word8 -> IO ByteString-unpackByteStringWithLength length ptr =-  B.packCStringLen (castPtr ptr, fromIntegral length)--unpackZeroTerminatedByteString :: Ptr Word8 -> IO ByteString-unpackZeroTerminatedByteString ptr =-  B.packCString (castPtr ptr)--packStorableArray :: Storable a => [a] -> IO (Ptr a)-packStorableArray = packMapStorableArray id--packZeroTerminatedStorableArray :: (Num a, Storable a) => [a] -> IO (Ptr a)-packZeroTerminatedStorableArray = packMapZeroTerminatedStorableArray id--unpackStorableArrayWithLength :: (Integral a, Storable b) =>-                                 a -> Ptr b -> IO [b]-unpackStorableArrayWithLength = unpackMapStorableArrayWithLength id--unpackZeroTerminatedStorableArray :: (Eq a, Num a, Storable a) =>-                                     Ptr a -> IO [a]-unpackZeroTerminatedStorableArray = unpackMapZeroTerminatedStorableArray id--packMapStorableArray :: forall a b. Storable b => (a -> b) -> [a] -> IO (Ptr b)-packMapStorableArray fn items = do-  let nitems = length items-  mem <- allocBytes $ (sizeOf (undefined::b)) * nitems-  fill mem (map fn items)-  return mem-  where fill            :: Ptr b -> [b] -> IO ()-        fill _ []       = return ()-        fill ptr (x:xs) = do-          poke ptr x-          fill (ptr `plusPtr` sizeOf x) xs--packMapZeroTerminatedStorableArray :: forall a b. (Num b, Storable b) =>-                                      (a -> b) -> [a] -> IO (Ptr b)-packMapZeroTerminatedStorableArray fn items = do-  let nitems = length items-  mem <- allocBytes $ (sizeOf (undefined::b)) * (nitems+1)-  fill mem (map fn items)-  return mem-  where fill            :: Ptr b -> [b] -> IO ()-        fill ptr []     = poke ptr 0-        fill ptr (x:xs) = do-          poke ptr x-          fill (ptr `plusPtr` sizeOf x) xs--unpackMapStorableArrayWithLength :: forall a b c. (Integral a, Storable b) =>-                                    (b -> c) -> a -> Ptr b -> IO [c]-unpackMapStorableArrayWithLength fn n ptr = map fn <$> go (fromIntegral n) ptr-    where go :: Int -> Ptr b -> IO [b]-          go 0 _ = return []-          go n ptr = do-            x <- peek ptr-            (x:) <$> go (n-1) (ptr `plusPtr` sizeOf x)--unpackMapZeroTerminatedStorableArray :: forall a b. (Eq a, Num a, Storable a) =>-                                        (a -> b) -> Ptr a -> IO [b]-unpackMapZeroTerminatedStorableArray fn ptr = map fn <$> go ptr-    where go :: Ptr a -> IO [a]-          go ptr = do-            x <- peek ptr-            if x == 0-            then return []-            else (x:) <$> go (ptr `plusPtr` sizeOf x)--packUTF8CArray :: [Text] -> IO (Ptr CString)-packUTF8CArray items = do-  let nitems = length items-  mem <- allocBytes $ nitems * (sizeOf (nullPtr :: CString))-  fill mem items-  return mem-    where fill            :: Ptr CString -> [Text] -> IO ()-          fill _ []       = return ()-          fill ptr (x:xs) =-              do cstring <- textToCString x-                 poke ptr cstring-                 fill (ptr `plusPtr` sizeOf cstring) xs--packZeroTerminatedUTF8CArray :: [Text] -> IO (Ptr CString)-packZeroTerminatedUTF8CArray items = do-    let nitems = length items-    mem <- allocBytes $ (sizeOf (nullPtr :: CString)) * (nitems+1)-    fill mem items-    return mem-    where fill :: Ptr CString -> [Text] -> IO ()-          fill ptr [] = poke ptr nullPtr-          fill ptr (x:xs) = do cstring <- textToCString x-                               poke ptr cstring-                               fill (ptr `plusPtr` sizeOf cstring) xs--unpackZeroTerminatedUTF8CArray :: Ptr CString -> IO [Text]-unpackZeroTerminatedUTF8CArray listPtr = go listPtr-    where go :: Ptr CString -> IO [Text]-          go ptr = do-            cstring <- peek ptr-            if cstring == nullPtr-               then return []-               else (:) <$> cstringToText cstring-                        <*> go (ptr `plusPtr` sizeOf cstring)--unpackUTF8CArrayWithLength :: Integral a => a -> Ptr CString -> IO [Text]-unpackUTF8CArrayWithLength n ptr = go (fromIntegral n) ptr-    where go       :: Int -> Ptr CString -> IO [Text]-          go 0 _   = return []-          go n ptr = do-            cstring <- peek ptr-            (:) <$> cstringToText cstring-                    <*> go (n-1) (ptr `plusPtr` sizeOf cstring)--packFileNameArray :: [String] -> IO (Ptr CString)-packFileNameArray items = do-  let nitems = length items-  mem <- allocBytes $ nitems * (sizeOf (nullPtr :: CString))-  fill mem items-  return mem-    where fill            :: Ptr CString -> [String] -> IO ()-          fill _ []       = return ()-          fill ptr (x:xs) =-              do cstring <- stringToCString x-                 poke ptr cstring-                 fill (ptr `plusPtr` sizeOf cstring) xs--packZeroTerminatedFileNameArray :: [String] -> IO (Ptr CString)-packZeroTerminatedFileNameArray items = do-    let nitems = length items-    mem <- allocBytes $ (sizeOf (nullPtr :: CString)) * (nitems+1)-    fill mem items-    return mem-    where fill :: Ptr CString -> [String] -> IO ()-          fill ptr [] = poke ptr nullPtr-          fill ptr (x:xs) = do cstring <- stringToCString x-                               poke ptr cstring-                               fill (ptr `plusPtr` sizeOf cstring) xs--unpackZeroTerminatedFileNameArray :: Ptr CString -> IO [String]-unpackZeroTerminatedFileNameArray listPtr = go listPtr-    where go :: Ptr CString -> IO [String]-          go ptr = do-            cstring <- peek ptr-            if cstring == nullPtr-               then return []-               else (:) <$> cstringToString cstring-                        <*> go (ptr `plusPtr` sizeOf cstring)--unpackFileNameArrayWithLength :: Integral a =>-                                 a -> Ptr CString -> IO [String]-unpackFileNameArrayWithLength n ptr = go (fromIntegral n) ptr-    where go       :: Int -> Ptr CString -> IO [String]-          go 0 _   = return []-          go n ptr = do-            cstring <- peek ptr-            (:) <$> cstringToString cstring-                    <*> go (n-1) (ptr `plusPtr` sizeOf cstring)--foreign import ccall "g_strdup" g_strdup :: CString -> IO CString---- We need to use the GLib allocator for constructing CStrings, since--- the ownership of the string may be transferred to the GLib side,--- which will free it with g_free.-stringToCString :: String -> IO CString-stringToCString str = withCString str g_strdup--cstringToString :: CString -> IO String-cstringToString = peekCString--foreign import ccall "g_strndup" g_strndup ::-    CString -> #{type gsize} -> IO CString---- | Convert `Text` into a `CString`, using the GLib allocator.-textToCString :: Text -> IO CString-textToCString str = TF.withCStringLen str $ \(cstr, len) ->-  -- Because withCStringLen returns NULL for a zero-length Text, and-  -- g_strndup returns NULL for NULL, even if n==0.-  if cstr /= nullPtr-  then g_strndup cstr (fromIntegral len)-  else callocBytes 1--withTextCString :: Text -> (CString -> IO a) -> IO a-withTextCString text action = bracket (textToCString text) freeMem action--foreign import ccall "strlen" c_strlen ::-    CString -> IO (CSize)--cstringToText :: CString -> IO Text-cstringToText cstr = do-  len <- c_strlen cstr-  let cstrlen = (cstr, fromIntegral len)-  TF.peekCStringLen cstrlen--byteStringToCString :: ByteString -> IO CString-byteStringToCString bs = B.useAsCString bs g_strdup--cstringToByteString :: CString -> IO ByteString-cstringToByteString = B.packCString--packPtrArray :: [Ptr a] -> IO (Ptr (Ptr a))-packPtrArray items = do-  let nitems = length items-  mem <- allocBytes $ (sizeOf (nullPtr :: Ptr a)) * nitems-  fill mem items-  return mem-  where fill :: Ptr (Ptr a) -> [Ptr a] -> IO ()-        fill _ [] = return ()-        fill ptr (x:xs) = do poke ptr x-                             fill (ptr `plusPtr` sizeOf x) xs--packZeroTerminatedPtrArray :: [Ptr a] -> IO (Ptr (Ptr a))-packZeroTerminatedPtrArray items = do-  let nitems = length items-  mem <- allocBytes $ (sizeOf (nullPtr :: Ptr a)) * (nitems+1)-  fill mem items-  return mem-  where fill            :: Ptr (Ptr a) -> [Ptr a] -> IO ()-        fill ptr []     = poke ptr nullPtr-        fill ptr (x:xs) = do poke ptr x-                             fill (ptr `plusPtr` sizeOf x) xs--unpackPtrArrayWithLength :: Integral a => a -> Ptr (Ptr b) -> IO [Ptr b]-unpackPtrArrayWithLength n ptr = go (fromIntegral n) ptr-    where go       :: Int -> Ptr (Ptr a) -> IO [Ptr a]-          go 0 _   = return []-          go n ptr = (:) <$> peek ptr-                     <*> go (n-1) (ptr `plusPtr` sizeOf (nullPtr :: Ptr a))--unpackZeroTerminatedPtrArray :: Ptr (Ptr a) -> IO [Ptr a]-unpackZeroTerminatedPtrArray ptr = go ptr-    where go :: Ptr (Ptr a) -> IO [Ptr a]-          go ptr = do-            p <- peek ptr-            if p == nullPtr-            then return []-            else (p:) <$> go (ptr `plusPtr` sizeOf p)--mapZeroTerminatedCArray :: (Ptr a -> IO b) -> Ptr (Ptr a) -> IO ()-mapZeroTerminatedCArray f dataPtr-    | (dataPtr == nullPtr) = return ()-    | otherwise =-        do ptr <- peek dataPtr-           if ptr == nullPtr-           then return ()-           else do-             _ <- f ptr-             mapZeroTerminatedCArray f (dataPtr `plusPtr` sizeOf ptr)--packBlockArray :: Int -> [Ptr a] -> IO (Ptr a)-packBlockArray size items = do-  let nitems = length items-  mem <- allocBytes $ size * nitems-  fill mem items-  return mem-  where fill :: Ptr a -> [Ptr a] -> IO ()-        fill _ [] = return ()-        fill ptr (x:xs) = do memcpy ptr x size-                             fill (ptr `plusPtr` size) xs--foreign import ccall "g_memdup" g_memdup ::-    Ptr a -> CUInt -> IO (Ptr a)--unpackBlockArrayWithLength :: Integral a => Int -> a -> Ptr b -> IO [Ptr b]-unpackBlockArrayWithLength size n ptr = go size (fromIntegral n) ptr-    where go       :: Int -> Int -> Ptr b -> IO [Ptr b]-          go _ 0 _   = return []-          go size n ptr = do-            buf <- g_memdup ptr (fromIntegral size)-            (buf :) <$> go size (n-1) (ptr `plusPtr` size)--unpackBoxedArrayWithLength :: forall a b. (Integral a, BoxedObject b) =>-                              Int -> a -> Ptr b -> IO [Ptr b]-unpackBoxedArrayWithLength size n ptr = go size (fromIntegral n) ptr-    where go       :: Int -> Int -> Ptr b -> IO [Ptr b]-          go _ 0 _   = return []-          go size n ptr = do-            buf <- copyBoxedPtr ptr-            (buf :) <$> go size (n-1) (ptr `plusPtr` size)--mapCArrayWithLength :: (Storable a, Integral b) =>-                       b -> (a -> IO c) -> Ptr a -> IO ()-mapCArrayWithLength n f dataPtr-    | (dataPtr == nullPtr) = return ()-    | (n <= 0) = return ()-    | otherwise =-        do ptr <- peek dataPtr-           _ <- f ptr-           mapCArrayWithLength (n-1) f (dataPtr `plusPtr` sizeOf ptr)--mapGArray :: forall a b. Storable a => (a -> IO b) -> Ptr (GArray a) -> IO ()-mapGArray f array-    | (array == nullPtr) = return ()-    | otherwise =-        do dataPtr <- peek (castPtr array :: Ptr (Ptr a))-           nitems <- peek (array `plusPtr` sizeOf dataPtr)-           go dataPtr nitems-               where go :: Ptr a -> Int -> IO ()-                     go _ 0 = return ()-                     go ptr n = do-                       x <- peek ptr-                       _ <- f x-                       go (ptr `plusPtr` sizeOf x) (n-1)--mapPtrArray :: (Ptr a -> IO b) -> Ptr (GPtrArray (Ptr a)) -> IO ()-mapPtrArray f array = mapGArray f (castPtr array)--mapGList :: (Ptr a -> IO b) -> Ptr (GList (Ptr a)) -> IO ()-mapGList f glist-    | (glist == nullPtr) = return ()-    | otherwise =-        do ptr <- peek (castPtr glist)-           next <- peek (glist `plusPtr` sizeOf ptr)-           _ <- f ptr-           mapGList f next--mapGSList :: (Ptr a -> IO b) -> Ptr (GSList (Ptr a)) -> IO ()-mapGSList f gslist = mapGList f (castPtr gslist)
− src/Data/GI/Base/BasicTypes.hs
@@ -1,206 +0,0 @@-{-# LANGUAGE ConstraintKinds, FlexibleContexts, FlexibleInstances,-  DeriveDataTypeable, TypeFamilies, ScopedTypeVariables #-}-#if !MIN_VERSION_base(4,8,0)-{-# LANGUAGE OverlappingInstances #-}-#endif-#if MIN_VERSION_base(4,9,0)-{-# LANGUAGE DataKinds, TypeOperators, UndecidableInstances #-}-#endif--- | Basic types used in the bindings.-module Data.GI.Base.BasicTypes-    (-      -- * GType related-      module Data.GI.Base.GType         -- reexported for convenience--     -- * Memory management--    , ForeignPtrNewtype-    , BoxedObject(..)-    , BoxedEnum(..)-    , BoxedFlags(..)-    , GObject(..)-    , WrappedPtr(..)-    , UnexpectedNullPointerReturn(..)-    , NullToNothing(..)--    -- * Basic GLib \/ GObject types-    , GVariant(..)-    , GParamSpec(..)--    , GArray(..)-    , GPtrArray(..)-    , GByteArray(..)-    , GHashTable(..)-    , GList(..)-    , g_list_free-    , GSList(..)-    , g_slist_free--    , IsGFlag--    , PtrWrapped(..)-    , GDestroyNotify-    ) where--#if !MIN_VERSION_base(4,8,0)-import Control.Applicative ((<$>))-#endif-import Control.Exception (Exception, catch)-import Control.Monad.IO.Class (MonadIO(..))-import Data.Coerce (Coercible)-import Data.Proxy (Proxy)-import qualified Data.Text as T-import Data.Typeable (Typeable)-import Foreign.Ptr (Ptr, FunPtr)-import Foreign.ForeignPtr (ForeignPtr)--#if MIN_VERSION_base(4,9,0)-import GHC.TypeLits-#endif--import Data.GI.Base.GType---- | A constraint ensuring that the given type is coercible to a--- ForeignPtr. It will hold for newtypes of the form------ > newtype Foo = Foo (ForeignPtr Foo)------ which is the typical shape of wrapped 'GObject's.-type ForeignPtrNewtype a = Coercible a (ForeignPtr ())--- Notice that the Coercible here is to ForeignPtr (), instead of--- "ForeignPtr a", which would be the most natural thing. Both are--- representationally equivalent, so this is not a big deal. This is--- to work around a problem in ghc 7.10:--- https://ghc.haskell.org/trac/ghc/ticket/10715---- | Wrapped boxed structures, identified by their `GType`.-class ForeignPtrNewtype a => BoxedObject a where-    boxedType :: a -> IO GType -- This should not use the value of its-                               -- argument.---- | Enums with an associated `GType`.-class BoxedEnum a where-    boxedEnumType :: a -> IO GType---- | Flags with an associated `GType`.-class BoxedFlags a where-    boxedFlagsType :: Proxy a -> IO GType---- | Pointers to structs/unions without an associated `GType`.-class ForeignPtrNewtype a => WrappedPtr a where-    -- | Allocate a zero-initialized block of memory for the given type.-    wrappedPtrCalloc :: IO (Ptr a)-    -- | Make a copy of the given pointer.-    wrappedPtrCopy   :: Ptr a -> IO (Ptr a)-    -- | A pointer to a function for freeing the given pointer, or-    -- `Nothing` is the memory associated to the pointer does not need-    -- to be freed.-    wrappedPtrFree   :: Maybe (FunPtr (Ptr a -> IO ()))---- | A wrapped `GObject`.-class ForeignPtrNewtype a => GObject a where-    -- | Whether the `GObject` is a descendent of <https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#GInitiallyUnowned GInitiallyUnowned>.-    gobjectIsInitiallyUnowned :: a -> Bool-    -- | The `GType` for this object.-    gobjectType :: a -> IO GType---- Raise a more understandable type error whenever the `GObject a`--- constraint is imposed on a type which has no such instance. This--- helps in the common case where one passes a wrong type (such as--- `Maybe Widget`) into a function with a `IsWidget a`--- constraint. Without this type error, the resulting type error is--- much less understandable, since GHC complains (at length) about a--- missing type family instance for `ParentTypes`.-#if MIN_VERSION_base(4,9,0)-instance {-# OVERLAPPABLE #-}-    (TypeError ('Text "Type ‘" ':<>: 'ShowType a ':<>:-                'Text "’ does not descend from GObject."), ForeignPtrNewtype a)-    => GObject a where-    gobjectIsInitiallyUnowned = undefined-    gobjectType = undefined-#endif---- | A common omission in the introspection data is missing (nullable)--- annotations for return types, when they clearly are nullable. (A--- common idiom is "Returns: valid value, or %NULL if something went--- wrong.")------ Haskell wrappers will raise this exception if the return value is--- an unexpected `Foreign.Ptr.nullPtr`.-data UnexpectedNullPointerReturn =-    UnexpectedNullPointerReturn { nullPtrErrorMsg :: T.Text }-                                deriving (Show, Typeable)--instance Exception UnexpectedNullPointerReturn--type family UnMaybe a :: * where-    UnMaybe (Maybe a) = a-    UnMaybe a         = a--class NullToNothing a where-    -- | Some functions are not marked as having a nullable return type-    -- in the introspection data.  The result is that they currently do-    -- not return a Maybe type.  This functions lets you work around this-    -- in a way that will not break when the introspection data is fixed.-    ---    -- When you want to call a `someHaskellGIFunction` that may return null-    -- wrap the call like this.-    ---    -- > nullToNothing (someHaskellGIFunction x y)-    ---    -- The result will be a Maybe type even if the introspection data has-    -- not been fixed for `someHaskellGIFunction` yet.-    nullToNothing :: MonadIO m => IO a -> m (Maybe (UnMaybe a))--instance-#if MIN_VERSION_base(4,8,0)-    {-# OVERLAPPABLE #-}-#endif-    a ~ UnMaybe a => NullToNothing a where-        nullToNothing f = liftIO $-            (Just <$> f) `catch` (\(_::UnexpectedNullPointerReturn) -> return Nothing)--instance NullToNothing (Maybe a) where-    nullToNothing = liftIO---- | A <https://developer.gnome.org/glib/stable/glib-GVariant.html GVariant>. See "Data.GI.Base.GVariant" for further methods.-newtype GVariant = GVariant (ForeignPtr GVariant)---- | A <https://developer.gnome.org/gobject/stable/gobject-GParamSpec.html GParamSpec>. See "Data.GI.Base.GParamSpec" for further methods.-newtype GParamSpec = GParamSpec (ForeignPtr GParamSpec)---- | An enum usable as a flag for a function.-class Enum a => IsGFlag a---- | A <https://developer.gnome.org/glib/stable/glib-Arrays.html GArray>. Marshalling for this type is done in "Data.GI.Base.BasicConversions", it is mapped to a list on the Haskell side.-data GArray a = GArray (Ptr (GArray a))---- | A <https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html GPtrArray>. Marshalling for this type is done in "Data.GI.Base.BasicConversions", it is mapped to a list on the Haskell side.-data GPtrArray a = GPtrArray (Ptr (GPtrArray a))---- | A <https://developer.gnome.org/glib/stable/glib-Byte-Arrays.html GByteArray>. Marshalling for this type is done in "Data.GI.Base.BasicConversions", it is packed to a 'Data.ByteString.ByteString' on the Haskell side.-data GByteArray = GByteArray (Ptr GByteArray)---- | A <https://developer.gnome.org/glib/stable/glib-Hash-Tables.html GHashTable>. It is mapped to a 'Data.Map.Map' on the Haskell side.-data GHashTable a b = GHashTable (Ptr (GHashTable a b))---- | A <https://developer.gnome.org/glib/stable/glib-Doubly-Linked-Lists.html GList>, mapped to a list on the Haskell side. Marshalling is done in "Data.GI.Base.BasicConversions".-data GList a = GList (Ptr (GList a))---- | A <https://developer.gnome.org/glib/stable/glib-Singly-Linked-Lists.html GSList>, mapped to a list on the Haskell side. Marshalling is done in "Data.GI.Base.BasicConversions".-data GSList a = GSList (Ptr (GSList a))---- | Some APIs, such as `GHashTable`, pass around scalar types--- wrapped into a pointer. We encode such a type as follows.-newtype PtrWrapped a = PtrWrapped {unwrapPtr :: Ptr a}---- | Destroy the memory associated with a given pointer.-type GDestroyNotify a = FunPtr (Ptr a -> IO ())---- | Free the given 'GList'.-foreign import ccall "g_list_free" g_list_free ::-    Ptr (GList a) -> IO ()---- | Free the given 'GSList'.-foreign import ccall "g_slist_free" g_slist_free ::-    Ptr (GSList a) -> IO ()
− src/Data/GI/Base/Closure.hs
@@ -1,41 +0,0 @@--- Some helper functions to create closures.-module Data.GI.Base.Closure-    ( Closure(..)-    , newCClosure-    , noClosure-    ) where--import Foreign--import Data.GI.Base.BasicTypes-import Data.GI.Base.ManagedPtr (wrapBoxed)-import Data.GI.Base.Utils (safeFreeFunPtrPtr)--newtype Closure = Closure (ForeignPtr Closure)--noClosure :: Maybe Closure-noClosure = Nothing--foreign import ccall "g_closure_get_type" c_g_closure_get_type ::-    IO GType--instance BoxedObject Closure where-    boxedType _ = c_g_closure_get_type---foreign import ccall "g_cclosure_new" g_cclosure_new-    :: FunPtr a -> Ptr () -> FunPtr c -> IO (Ptr Closure)--foreign import ccall "g_closure_ref" g_closure_ref-    :: Ptr Closure -> IO (Ptr Closure)--foreign import ccall "g_closure_sink" g_closure_sink-    :: Ptr Closure -> IO ()--newCClosure :: FunPtr a -> IO Closure-newCClosure ptr = do-  closure <- g_cclosure_new ptr nullPtr safeFreeFunPtrPtr-  -- The Haskell runtime will manage the memory associated to the-  -- closure, so ref and sink to let GLib know this.-  g_closure_ref closure >>= g_closure_sink-  wrapBoxed Closure closure
− src/Data/GI/Base/Constructible.hs
@@ -1,32 +0,0 @@-{-# LANGUAGE DataKinds, FlexibleInstances, MultiParamTypeClasses,-  UndecidableInstances, KindSignatures, TypeFamilies #-}-#if !MIN_VERSION_base(4,8,0)-{-# LANGUAGE OverlappingInstances #-}-#endif---- | `Constructible` types are those for which `new` is--- defined. Often these are `GObject`s, but it is possible to--- construct new (zero-initialized) structures and unions too.--module Data.GI.Base.Constructible-    ( Constructible(..)-    ) where--import Foreign (ForeignPtr)-import Control.Monad.IO.Class (MonadIO)--import Data.GI.Base.Attributes (AttrOp, AttrOpTag(..))-import Data.GI.Base.BasicTypes (GObject)-import Data.GI.Base.GObject (constructGObject)---- | Constructible types, i.e. those which can be allocated by `new`.-class Constructible a (tag :: AttrOpTag) where-    new :: MonadIO m => (ForeignPtr a -> a) -> [AttrOp a tag] -> m a---- | Default instance, assuming we have a `GObject`.-instance-#if MIN_VERSION_base(4,8,0)-    {-# OVERLAPPABLE #-}-#endif-    (GObject a, tag ~ 'AttrConstruct) => Constructible a tag where-        new = constructGObject
− src/Data/GI/Base/GError.hsc
@@ -1,240 +0,0 @@-{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables #-}---- | To catch GError exceptions use the--- catchGError* or handleGError* functions. They work in a similar--- way to the standard 'Control.Exception.catch' and--- 'Control.Exception.handle' functions.------ To catch just a single specific error use 'catchGErrorJust' \/--- 'handleGErrorJust'. To catch any error in a particular error domain--- use 'catchGErrorJustDomain' \/ 'handleGErrorJustDomain'------ For convenience, generated code also includes specialized variants--- of 'catchGErrorJust' \/ 'handleGErrorJust' for each error type. For--- example, for errors of type 'GI.GdkPixbuf.PixbufError' one could--- invoke 'GI.GdkPixbuf.catchPixbufError' \/--- 'GI.GdkPixbuf.handlePixbufError'. The definition is simply------ > catchPixbufError :: IO a -> (PixbufError -> GErrorMessage -> IO a) -> IO a--- > catchPixbufError = catchGErrorJustDomain------ Notice that the type is suitably specialized, so only--- errors of type 'GI.GdkPixbuf.PixbufError' will be caught.-module Data.GI.Base.GError-    (-    -- * Unpacking GError-    ---      GError(..)-    , gerrorDomain-    , gerrorCode-    , gerrorMessage--    , GErrorDomain-    , GErrorCode-    , GErrorMessage--    -- * Catching GError exceptions-    , catchGErrorJust-    , catchGErrorJustDomain--    , handleGErrorJust-    , handleGErrorJustDomain--    -- * Creating new 'GError's-    , gerrorNew--    -- * Implementation specific details-    -- | The following are used in the implementation-    -- of the bindings, and are in general not necessary for using the-    -- API.-    , GErrorClass(..)--    , propagateGError-    , checkGError--    ) where--#if __GLASGOW_HASKELL__ < 710-import Control.Applicative ((<$>))-#endif--import Foreign (poke, peek)-import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)-import Foreign.Ptr (Ptr, plusPtr, nullPtr)-import Foreign.C-import Control.Exception-import Data.Text (Text)-import Data.Typeable (Typeable)-import Data.Int-import Data.Word--import Data.GI.Base.BasicTypes (BoxedObject(..), GType(..))-import Data.GI.Base.BasicConversions (withTextCString, cstringToText)-import Data.GI.Base.ManagedPtr (wrapBoxed)-import Data.GI.Base.Utils (allocMem, freeMem)--#include <glib.h>---- | A GError, consisting of a domain, code and a human readable--- message. These can be accessed by 'gerrorDomain', 'gerrorCode' and--- 'gerrorMessage' below.-newtype GError = GError (ForeignPtr GError)-    deriving (Typeable, Show)--instance Exception GError--foreign import ccall "g_error_get_type" g_error_get_type :: IO GType--instance BoxedObject GError where-    boxedType _ = g_error_get_type---- | A GQuark.-type GQuark = #type GQuark---- | A code used to identify the "namespace" of the error. Within each error---   domain all the error codes are defined in an enumeration. Each gtk\/gnome---   module that uses GErrors has its own error domain. The rationale behind---   using error domains is so that each module can organise its own error codes---   without having to coordinate on a global error code list.-type GErrorDomain  = GQuark---- | A code to identify a specific error within a given 'GErrorDomain'. Most of---   time you will not need to deal with this raw code since there is an---   enumeration type for each error domain. Of course which enumeration to use---   depends on the error domain, but if you use 'catchGErrorJustDomain' or---   'handleGErrorJustDomain', this is worked out for you automatically.-type GErrorCode = #type gint---- | A human readable error message.-type GErrorMessage = Text--foreign import ccall "g_error_new_literal" g_error_new_literal ::-    GQuark -> GErrorCode -> CString -> IO (Ptr GError)---- | Create a new 'GError'.-gerrorNew :: GErrorDomain -> GErrorCode -> GErrorMessage -> IO GError-gerrorNew domain code message =-    withTextCString message $ \cstring ->-        g_error_new_literal domain code cstring >>= wrapBoxed GError---- | Return the domain for the given `GError`. This is a GQuark, a--- textual representation can be obtained with--- `GI.GLib.quarkToString`.-gerrorDomain :: GError -> IO GQuark-gerrorDomain (GError fptr) =-    withForeignPtr fptr $ \ptr ->-      peek $ ptr `plusPtr` #{offset GError, domain}---- | The numeric code for the given `GError`.-gerrorCode :: GError -> IO GErrorCode-gerrorCode (GError fptr) =-    withForeignPtr fptr $ \ptr ->-        peek $ ptr `plusPtr` #{offset GError, code}---- | A text message describing the `GError`.-gerrorMessage :: GError -> IO GErrorMessage-gerrorMessage (GError fptr) =-    withForeignPtr fptr $ \ptr ->-      (peek $ ptr `plusPtr` #{offset GError, message}) >>= cstringToText---- | Each error domain's error enumeration type should be an instance of this---   class. This class helps to hide the raw error and domain codes from the---   user.------ Example for 'GI.GdkPixbuf.PixbufError':------ > instance GErrorClass PixbufError where--- >   gerrorClassDomain _ = "gdk-pixbuf-error-quark"----class Enum err => GErrorClass err where-  gerrorClassDomain :: err -> Text   -- ^ This must not use the value of its-                                     -- parameter so that it is safe to pass-                                     -- 'undefined'.--foreign import ccall unsafe "g_quark_try_string" g_quark_try_string ::-    CString -> IO GQuark---- | Given the string representation of an error domain returns the---   corresponding error quark.-gErrorQuarkFromDomain :: Text -> IO GQuark-gErrorQuarkFromDomain domain = withTextCString domain g_quark_try_string---- | This will catch just a specific GError exception. If you need to catch a---   range of related errors, 'catchGErrorJustDomain' is probably more---   appropriate. Example:------ > do image <- catchGErrorJust PixbufErrorCorruptImage--- >               loadImage--- >               (\errorMessage -> do log errorMessage--- >                                    return mssingImagePlaceholder)----catchGErrorJust :: GErrorClass err => err  -- ^ The error to catch-                -> IO a                    -- ^ The computation to run-                -> (GErrorMessage -> IO a) -- ^ Handler to invoke if-                                           -- an exception is raised-                -> IO a-catchGErrorJust code action handler = do-  domainQuark <- gErrorQuarkFromDomain $ gerrorClassDomain code-  catch action (handler' domainQuark)-  where handler' quark gerror = do-          domain <- gerrorDomain gerror-          code' <- gerrorCode gerror-          if domain == quark && code' == (fromIntegral . fromEnum) code-          then gerrorMessage gerror >>= handler-          else throw gerror -- Pass it on---- | Catch all GErrors from a particular error domain. The handler function---   should just deal with one error enumeration type. If you need to catch---   errors from more than one error domain, use this function twice with an---   appropriate handler functions for each.------ > catchGErrorJustDomain--- >   loadImage--- >   (\err message -> case err of--- >       PixbufErrorCorruptImage -> ...--- >       PixbufErrorInsufficientMemory -> ...--- >       PixbufErrorUnknownType -> ...--- >       _ -> ...)----catchGErrorJustDomain :: forall err a. GErrorClass err =>-                         IO a        -- ^ The computation to run-                      -> (err -> GErrorMessage -> IO a) -- ^ Handler to invoke if an exception is raised-                      -> IO a-catchGErrorJustDomain action handler = do-  domainQuark <- gErrorQuarkFromDomain $ gerrorClassDomain (undefined::err)-  catch action (handler' domainQuark)-  where handler' quark gerror = do-          domain <- gerrorDomain gerror-          if domain == quark-          then do-            code <- (toEnum . fromIntegral) <$> gerrorCode gerror-            msg <- gerrorMessage gerror-            handler code msg-          else throw gerror---- | A verson of 'handleGErrorJust' with the arguments swapped around.-handleGErrorJust :: GErrorClass err => err -> (GErrorMessage -> IO a) -> IO a -> IO a-handleGErrorJust code = flip (catchGErrorJust code)---- | A verson of 'catchGErrorJustDomain' with the arguments swapped around.-handleGErrorJustDomain :: GErrorClass err => (err -> GErrorMessage -> IO a) -> IO a -> IO a-handleGErrorJustDomain = flip catchGErrorJustDomain---- | Run the given function catching possible 'GError's in its--- execution. If a 'GError' is emitted this throws the corresponding--- exception.-propagateGError :: (Ptr (Ptr GError) -> IO a) -> IO a-propagateGError f = checkGError f throw---- | Like 'propagateGError', but allows to specify a custom handler--- instead of just throwing the exception.-checkGError :: (Ptr (Ptr GError) -> IO a) -> (GError -> IO a) -> IO a-checkGError f handler = do-  gerrorPtr <- allocMem-  poke gerrorPtr nullPtr-  result <- f gerrorPtr-  gerror <- peek gerrorPtr-  freeMem gerrorPtr-  if gerror /= nullPtr-  then wrapBoxed GError gerror >>= handler-  else return result
− src/Data/GI/Base/GHashTable.hsc
@@ -1,68 +0,0 @@-{- | Machinery for some basic support of `GHashTable`.--The GLib `GHashTable` implementation requires two things: we need to-"pack" a datatype into a pointer (for datatypes that are represented-by pointers this is the trivial operation, for integers it is not, and-GLib has some helper macros).--We also need to be able to hash and check for equality different-datatypes.--}-module Data.GI.Base.GHashTable-    ( GHashFunc-    , GEqualFunc--    , gDirectHash-    , gDirectEqual-    , ptrPackPtr-    , ptrUnpackPtr--    , gStrHash-    , gStrEqual-    , cstringPackPtr-    , cstringUnpackPtr-    ) where--import Data.Int-import Data.Word--import Foreign.C-import Foreign.Ptr (Ptr, castPtr, FunPtr)--import Data.GI.Base.BasicTypes (PtrWrapped(..))--#include <glib-object.h>---- | A pointer to a hashing function on the C side.-type GHashFunc a = FunPtr (PtrWrapped a -> IO #{type guint})---- | A pointer to an equality checking function on the C side.-type GEqualFunc a = FunPtr (PtrWrapped a -> PtrWrapped a -> IO #{type gboolean})---- | Compute the hash for a `Ptr`.-foreign import ccall "&g_direct_hash" gDirectHash :: GHashFunc (Ptr a)---- | Check whether two pointers are equal.-foreign import ccall "&g_direct_equal" gDirectEqual :: GEqualFunc (Ptr a)---- | Pack a `Ptr` into a `PtrWrapped` `Ptr`.-ptrPackPtr :: Ptr a -> PtrWrapped (Ptr a)-ptrPackPtr = PtrWrapped . castPtr---- | Extract a `Ptr` from a `PtrWrapped` `Ptr`.-ptrUnpackPtr :: PtrWrapped (Ptr a) -> Ptr a-ptrUnpackPtr = castPtr . unwrapPtr---- | Compute the hash for a `CString`.-foreign import ccall "&g_str_hash" gStrHash :: GHashFunc CString---- | Check whether two `CString`s are equal.-foreign import ccall "&g_str_equal" gStrEqual :: GEqualFunc CString---- | Pack a `CString` into a `Ptr` than can go into a `GHashTable`.-cstringPackPtr :: CString -> PtrWrapped CString-cstringPackPtr = ptrPackPtr---- | Extract a `CString` wrapped into a `Ptr` coming from a `GHashTable`.-cstringUnpackPtr :: PtrWrapped CString -> CString-cstringUnpackPtr = ptrUnpackPtr
− src/Data/GI/Base/GObject.hsc
@@ -1,98 +0,0 @@-{-# LANGUAGE ScopedTypeVariables, DataKinds, TypeFamilies #-}--module Data.GI.Base.GObject-    ( constructGObject-    , new'-    ) where--import Control.Monad.IO.Class (MonadIO, liftIO)-import Data.Proxy (Proxy(..))--import Foreign.C (CUInt(..), CString, newCString)-import Foreign--import Data.GI.Base.Attributes (AttrOp(..), AttrOpTag(..), AttrLabelProxy,-                                attrConstruct)-import Data.GI.Base.BasicTypes (GType(..), GObject(..))-import Data.GI.Base.GValue (GValue(..), GValueConstruct(..))-import Data.GI.Base.ManagedPtr (withManagedPtr, touchManagedPtr, wrapObject)-import Data.GI.Base.Overloading (ResolveAttribute)--#include <glib-object.h>--foreign import ccall "dbg_g_object_newv" g_object_newv ::-    GType -> CUInt -> Ptr a -> IO (Ptr b)---- | Construct a GObject given the constructor and a list of settable--- attributes.-constructGObject :: forall o m. (GObject o, MonadIO m)-    => (ForeignPtr o -> o)-    -> [AttrOp o 'AttrConstruct]-    -> m o-constructGObject constructor attrs = liftIO $ do-  props <- mapM construct attrs-  doConstructGObject constructor props-  where-    resolve :: AttrLabelProxy attr -> Proxy (ResolveAttribute attr o)-    resolve _ = Proxy--    construct :: AttrOp o 'AttrConstruct ->-                 IO (GValueConstruct o)-    construct (attr := x) = attrConstruct (resolve attr) x-    construct (attr :=> x) = x >>= attrConstruct (resolve attr)---- | Construct the `GObject` given the list of `GValueConstruct`s.-doConstructGObject :: forall o m. (GObject o, MonadIO m)-                      => (ForeignPtr o -> o) -> [GValueConstruct o] -> m o-doConstructGObject constructor props = liftIO $ do-  let nprops = length props-  params <- mallocBytes (nprops*gparameterSize)-  fill params props-  gtype <- gobjectType (undefined :: o)-  result <- g_object_newv gtype (fromIntegral nprops) params-  freeStrings nprops params-  free params-  -- Make sure that the GValues defining the GProperties are still-  -- alive at this point (so, in particular, they are still alive when-  -- g_object_newv is called). Without this the GHC garbage collector-  -- may free the GValues before g_object_newv is called, which will-  -- unref the referred to objects, which may drop the last reference-  -- to the contained objects. g_object_newv then tries to access the-  -- (now invalid) contents of the GValue, and mayhem ensues.-  mapM_ (touchManagedPtr . deconstructGValue) props-  wrapObject constructor (result :: Ptr o)--  where-    deconstructGValue :: GValueConstruct o -> GValue-    deconstructGValue (GValueConstruct _ v) = v--    gvalueSize = #size GValue-    gparameterSize = #size GParameter--    -- Fill the given memory address with the contents of the array of-    -- GParameters.-    fill :: Ptr () -> [GValueConstruct o] -> IO ()-    fill _ [] = return ()-    fill dataPtr ((GValueConstruct str gvalue):xs) =-        do cstr <- newCString str-           poke (castPtr dataPtr) cstr-           withManagedPtr gvalue $ \gvalueptr ->-               copyBytes (dataPtr `plusPtr` sizeOf nullPtr) gvalueptr gvalueSize-           fill (dataPtr `plusPtr` gparameterSize) xs--    -- Free the strings in the GParameter array (the GValues will be-    -- freed separately).-    freeStrings :: Int -> Ptr () -> IO ()-    freeStrings 0 _ = return ()-    freeStrings n dataPtr =-        do cstr <- peek (castPtr dataPtr) :: IO CString-           free cstr-           freeStrings (n-1) (dataPtr `plusPtr` gparameterSize)---- | Construct the given `GObject`, given a set of actions--- constructing desired `GValue`s to set at construction time.-new' :: (MonadIO m, GObject o) =>-        (ForeignPtr o -> o) -> [IO (GValueConstruct o)] -> m o-new' constructor actions = do-  props <- liftIO $ sequence (actions)-  doConstructGObject constructor props
− src/Data/GI/Base/GParamSpec.hsc
@@ -1,51 +0,0 @@-module Data.GI.Base.GParamSpec-    ( noGParamSpec--    , wrapGParamSpecPtr-    , newGParamSpecFromPtr-    , refGParamSpec-    , unrefGParamSpec-    ) where--import Foreign.Ptr-import Foreign.ForeignPtr (withForeignPtr)-import Control.Monad (void)--import Data.GI.Base.ManagedPtr (newManagedPtr)-import Data.GI.Base.BasicTypes (GParamSpec(..))--#include <glib-object.h>--noGParamSpec :: Maybe GParamSpec-noGParamSpec = Nothing--foreign import ccall "g_param_spec_ref_sink" g_param_spec_ref_sink ::-    Ptr GParamSpec -> IO (Ptr GParamSpec)-foreign import ccall "g_param_spec_ref" g_param_spec_ref ::-    Ptr GParamSpec -> IO (Ptr GParamSpec)-foreign import ccall "g_param_spec_unref" g_param_spec_unref ::-    Ptr GParamSpec -> IO ()-foreign import ccall "&g_param_spec_unref" ptr_to_g_param_spec_unref ::-    FunPtr (Ptr GParamSpec -> IO ())---- | Take ownership of a ParamSpec passed in 'Ptr'.-wrapGParamSpecPtr :: Ptr GParamSpec -> IO GParamSpec-wrapGParamSpecPtr ptr = do-  void $ g_param_spec_ref_sink ptr-  fPtr <- newManagedPtr ptr_to_g_param_spec_unref ptr-  return $! GParamSpec fPtr---- | Construct a Haskell wrapper for the given 'GParamSpec', without--- assuming ownership.-newGParamSpecFromPtr :: Ptr GParamSpec -> IO GParamSpec-newGParamSpecFromPtr ptr = do-  fPtr <- g_param_spec_ref ptr >>= newManagedPtr ptr_to_g_param_spec_unref-  return $! GParamSpec fPtr---- | Add a reference to the given 'GParamSpec'.-refGParamSpec :: GParamSpec -> IO (Ptr GParamSpec)-refGParamSpec (GParamSpec fptr) = withForeignPtr fptr g_param_spec_ref---- | Remove a reference to the given 'GParamSpec'.-unrefGParamSpec :: GParamSpec -> IO ()-unrefGParamSpec (GParamSpec fptr) = withForeignPtr fptr g_param_spec_unref
− src/Data/GI/Base/GType.hsc
@@ -1,142 +0,0 @@--- | Basic `GType`s.-module Data.GI.Base.GType-    ( GType(..)-    , CGType--    , gtypeName--    , gtypeString-    , gtypePointer-    , gtypeInt-    , gtypeUInt-    , gtypeLong-    , gtypeULong-    , gtypeInt64-    , gtypeUInt64-    , gtypeFloat-    , gtypeDouble-    , gtypeBoolean-    , gtypeGType-    , gtypeStrv-    , gtypeBoxed-    , gtypeObject-    , gtypeVariant-    , gtypeByteArray-    , gtypeInvalid-    ) where--import Data.Word-import Foreign.C.String (CString, peekCString)--#include <glib-object.h>---- | A type identifier in the GLib type system. This is the low-level--- type associated with the representation in memory, when using this--- on the Haskell side use `GType` below.-type CGType = #type GType---- | A newtype for use on the haskell side.-newtype GType = GType {gtypeToCGType :: CGType}--foreign import ccall "g_type_name" g_type_name :: GType -> IO CString---- | Get the name assigned to the given `GType`.-gtypeName :: GType -> IO String-gtypeName gtype = g_type_name gtype >>= peekCString--{-| [Note: compile-time vs run-time GTypes]--Notice that there are two types of GType's: the fundamental ones,-which are created with G_TYPE_MAKE_FUNDAMENTAL(n) and always have the-same runtime representation, and the ones that are registered in the-GObject type system at runtime, and whose `CGType` may change for each-program run (and generally does).--For the first type it is safe to use hsc to read the numerical values-of the CGType at compile type, but for the second type it is essential-to call the corresponding _get_type() function at runtime, and not use-the value of the corresponding "constant" at compile time via hsc.--}--{- Fundamental types -}---- | `GType` of strings.-gtypeString :: GType-gtypeString = GType #const G_TYPE_STRING---- | `GType` of pointers.-gtypePointer :: GType-gtypePointer = GType #const G_TYPE_POINTER---- | `GType` for signed integers (`gint` or `gint32`).-gtypeInt :: GType-gtypeInt = GType #const G_TYPE_INT---- | `GType` for unsigned integers (`guint` or `guint32`).-gtypeUInt :: GType-gtypeUInt = GType #const G_TYPE_UINT---- | `GType` for `glong`.-gtypeLong :: GType-gtypeLong = GType #const G_TYPE_LONG---- | `GType` for `gulong`.-gtypeULong :: GType-gtypeULong = GType #const G_TYPE_ULONG---- | `GType` for signed 64 bit integers.-gtypeInt64 :: GType-gtypeInt64 = GType #const G_TYPE_INT64---- | `GType` for unsigned 64 bit integers.-gtypeUInt64 :: GType-gtypeUInt64 = GType #const G_TYPE_UINT64---- | `GType` for floating point values.-gtypeFloat :: GType-gtypeFloat = GType #const G_TYPE_FLOAT---- | `GType` for gdouble.-gtypeDouble :: GType-gtypeDouble = GType #const G_TYPE_DOUBLE---- | `GType` corresponding to gboolean.-gtypeBoolean :: GType-gtypeBoolean = GType #const G_TYPE_BOOLEAN---- | `GType` corresponding to a `BoxedObject`.-gtypeBoxed :: GType-gtypeBoxed = GType #const G_TYPE_BOXED---- | `GType` corresponding to a `GObject`.-gtypeObject :: GType-gtypeObject = GType #const G_TYPE_OBJECT---- | An invalid `GType` used as error return value in some functions--- which return a `GType`.-gtypeInvalid :: GType-gtypeInvalid = GType #const G_TYPE_INVALID---- | The `GType` corresponding to a `GVariant`.-gtypeVariant :: GType-gtypeVariant = GType #const G_TYPE_VARIANT--{- Run-time types -}--foreign import ccall "g_gtype_get_type" g_gtype_get_type :: CGType---- | `GType` corresponding to a `GType` itself.-gtypeGType :: GType-gtypeGType = GType g_gtype_get_type--foreign import ccall "g_strv_get_type" g_strv_get_type :: CGType---- | `GType` for a NULL terminated array of strings.-gtypeStrv :: GType-gtypeStrv = GType g_strv_get_type--foreign import ccall "g_byte_array_get_type" g_byte_array_get_type :: CGType---- | `GType` for a boxed type holding a `GByteArray`.-gtypeByteArray :: GType-gtypeByteArray = GType g_byte_array_get_type
− src/Data/GI/Base/GValue.hsc
@@ -1,379 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-module Data.GI.Base.GValue-    ( GValue(..)-    , IsGValue(..)--    , newGValue         -- Build a new, empty, GValue of the given type-    , buildGValue       -- Build a new GValue and initialize to the given value-    , noGValue--    , GValueConstruct(..)--    , set_string-    , get_string-    , set_pointer-    , get_pointer-    , set_int-    , get_int-    , set_uint-    , get_uint-    , set_long-    , get_long-    , set_ulong-    , get_ulong-    , set_int32-    , get_int32-    , set_uint32-    , get_uint32-    , set_int64-    , get_int64-    , set_uint64-    , get_uint64-    , set_float-    , get_float-    , set_double-    , get_double-    , set_boolean-    , get_boolean-    , set_gtype-    , get_gtype-    , set_object-    , get_object-    , set_boxed-    , get_boxed-    , set_variant-    , get_variant-    , set_enum-    , get_enum-    , set_flags-    , get_flags-    ) where--#include <glib-object.h>--#if !MIN_VERSION_base(4,8,0)-import Control.Applicative ((<$>))-#endif--import Data.Coerce (coerce)-import Data.Word-import Data.Int-import Data.Text (Text, pack, unpack)--import Foreign.C.Types (CInt(..), CUInt(..), CFloat(..), CDouble(..),-                        CLong(..), CULong(..))-import Foreign.C.String (CString)-import Foreign.Ptr (Ptr, nullPtr)-import Foreign.ForeignPtr (ForeignPtr)--import Data.GI.Base.BasicTypes-import Data.GI.Base.BasicConversions (cstringToText, textToCString)-import Data.GI.Base.ManagedPtr-import Data.GI.Base.Utils (callocBytes, freeMem)--newtype GValue = GValue (ForeignPtr GValue)--noGValue :: Maybe GValue-noGValue = Nothing--foreign import ccall unsafe "g_value_get_type" c_g_value_get_type ::-    IO CGType--instance BoxedObject GValue where-    boxedType _ = GType <$> c_g_value_get_type--foreign import ccall "g_value_init" g_value_init ::-    Ptr GValue -> CGType -> IO (Ptr GValue)---- | A type holding a `GValue` with an associated label. It is--- parameterized by a phantom type encoding the target type for the--- `GValue` (useful when constructing properties).-data GValueConstruct o = GValueConstruct String GValue--newGValue :: GType -> IO GValue-newGValue (GType gtype) = do-  gvptr <- callocBytes #size GValue-  _ <- g_value_init gvptr gtype-  gv <- wrapBoxed GValue gvptr-  return $! gv---- Build a new GValue and set the initial value, just for convenience-buildGValue :: GType -> (GValue -> a -> IO ()) -> a -> IO GValue-buildGValue gtype setter val = do-  gv <- newGValue gtype-  setter gv val-  return gv--class IsGValue a where-    toGValue :: a -> IO GValue-    fromGValue :: GValue -> IO a--instance IsGValue (Maybe String) where-    toGValue = buildGValue gtypeString set_string . fmap pack-    fromGValue v = (fmap unpack) <$> get_string v--instance IsGValue (Maybe Text) where-    toGValue = buildGValue gtypeString set_string-    fromGValue = get_string--instance IsGValue (Ptr a) where-    toGValue = buildGValue gtypePointer set_pointer-    fromGValue = get_pointer--instance IsGValue Int32 where-    toGValue = buildGValue gtypeInt set_int32-    fromGValue = get_int32--instance IsGValue Word32 where-    toGValue = buildGValue gtypeUInt set_uint32-    fromGValue = get_uint32--instance IsGValue CInt where-    toGValue = buildGValue gtypeInt set_int-    fromGValue = get_int--instance IsGValue CUInt where-    toGValue = buildGValue gtypeUInt set_uint-    fromGValue = get_uint--instance IsGValue CLong where-    toGValue = buildGValue gtypeLong set_long-    fromGValue = get_long--instance IsGValue CULong where-    toGValue = buildGValue gtypeULong set_ulong-    fromGValue = get_ulong--instance IsGValue Int64 where-    toGValue = buildGValue gtypeInt64 set_int64-    fromGValue = get_int64--instance IsGValue Word64 where-    toGValue = buildGValue gtypeUInt64 set_uint64-    fromGValue = get_uint64--instance IsGValue Float where-    toGValue = buildGValue gtypeFloat set_float-    fromGValue = get_float--instance IsGValue Double where-    toGValue = buildGValue gtypeDouble set_double-    fromGValue = get_double--instance IsGValue Bool where-    toGValue = buildGValue gtypeBoolean set_boolean-    fromGValue = get_boolean--instance IsGValue GType where-    toGValue = buildGValue gtypeGType set_gtype-    fromGValue = get_gtype--foreign import ccall "g_value_set_string" _set_string ::-    Ptr GValue -> CString -> IO ()-foreign import ccall "g_value_get_string" _get_string ::-    Ptr GValue -> IO CString--set_string :: GValue -> Maybe Text -> IO ()-set_string gv maybeStr =-    withManagedPtr gv $ \ptr -> do-      cstr <- case maybeStr of-                Just str -> textToCString str-                Nothing -> return nullPtr-      _set_string ptr cstr-      freeMem cstr--get_string :: GValue -> IO (Maybe Text)-get_string gv = withManagedPtr gv $ \gvptr -> do-                  cstr <- _get_string gvptr-                  if cstr /= nullPtr-                  then Just <$> cstringToText cstr-                  else return Nothing--foreign import ccall unsafe "g_value_set_pointer" _set_pointer ::-    Ptr GValue -> Ptr a -> IO ()-foreign import ccall unsafe "g_value_get_pointer" _get_pointer ::-    Ptr GValue -> IO (Ptr b)--set_pointer :: GValue -> Ptr a -> IO ()-set_pointer gv ptr = withManagedPtr gv $ flip _set_pointer ptr--get_pointer :: GValue -> IO (Ptr b)-get_pointer gv = withManagedPtr gv _get_pointer--foreign import ccall unsafe "g_value_set_int" _set_int ::-    Ptr GValue -> CInt -> IO ()-foreign import ccall unsafe "g_value_get_int" _get_int ::-    Ptr GValue -> IO CInt--set_int32 :: GValue -> Int32 -> IO ()-set_int32 gv n = withManagedPtr gv $ flip _set_int (coerce n)--get_int32 :: GValue -> IO Int32-get_int32 gv = coerce <$> withManagedPtr gv _get_int--set_int :: GValue -> CInt -> IO ()-set_int gv n = withManagedPtr gv $ flip _set_int n--get_int :: GValue -> IO CInt-get_int gv = withManagedPtr gv _get_int--foreign import ccall unsafe "g_value_set_uint" _set_uint ::-    Ptr GValue -> CUInt -> IO ()-foreign import ccall unsafe "g_value_get_uint" _get_uint ::-    Ptr GValue -> IO CUInt--set_uint32 :: GValue -> Word32 -> IO ()-set_uint32 gv n = withManagedPtr gv $ flip _set_uint (coerce n)--get_uint32 :: GValue -> IO Word32-get_uint32 gv = coerce <$> withManagedPtr gv _get_uint--set_uint :: GValue -> CUInt -> IO ()-set_uint gv n = withManagedPtr gv $ flip _set_uint n--get_uint :: GValue -> IO CUInt-get_uint gv = withManagedPtr gv _get_uint--foreign import ccall unsafe "g_value_set_long" _set_long ::-    Ptr GValue -> CLong -> IO ()-foreign import ccall unsafe "g_value_get_long" _get_long ::-    Ptr GValue -> IO CLong--set_long :: GValue -> CLong -> IO ()-set_long gv n = withManagedPtr gv $ flip _set_long n--get_long :: GValue -> IO CLong-get_long gv = withManagedPtr gv _get_long--foreign import ccall unsafe "g_value_set_ulong" _set_ulong ::-    Ptr GValue -> CULong -> IO ()-foreign import ccall unsafe "g_value_get_ulong" _get_ulong ::-    Ptr GValue -> IO CULong--set_ulong :: GValue -> CULong -> IO ()-set_ulong gv n = withManagedPtr gv $ flip _set_ulong n--get_ulong :: GValue -> IO CULong-get_ulong gv = withManagedPtr gv _get_ulong--foreign import ccall unsafe "g_value_set_int64" _set_int64 ::-    Ptr GValue -> Int64 -> IO ()-foreign import ccall unsafe "g_value_get_int64" _get_int64 ::-    Ptr GValue -> IO Int64--set_int64 :: GValue -> Int64 -> IO ()-set_int64 gv n = withManagedPtr gv $ flip _set_int64 n--get_int64 :: GValue -> IO Int64-get_int64 gv = withManagedPtr gv _get_int64--foreign import ccall unsafe "g_value_set_uint64" _set_uint64 ::-    Ptr GValue -> Word64 -> IO ()-foreign import ccall unsafe "g_value_get_uint64" _get_uint64 ::-    Ptr GValue -> IO Word64--set_uint64 :: GValue -> Word64 -> IO ()-set_uint64 gv n = withManagedPtr gv $ flip _set_uint64 n--get_uint64 :: GValue -> IO Word64-get_uint64 gv = withManagedPtr gv _get_uint64--foreign import ccall unsafe "g_value_set_float" _set_float ::-    Ptr GValue -> CFloat -> IO ()-foreign import ccall unsafe "g_value_get_float" _get_float ::-    Ptr GValue -> IO CFloat--set_float :: GValue -> Float -> IO ()-set_float gv f = withManagedPtr gv $ flip _set_float (realToFrac f)--get_float :: GValue -> IO Float-get_float gv = realToFrac <$> withManagedPtr gv _get_float--foreign import ccall unsafe "g_value_set_double" _set_double ::-    Ptr GValue -> CDouble -> IO ()-foreign import ccall unsafe "g_value_get_double" _get_double ::-    Ptr GValue -> IO CDouble--set_double :: GValue -> Double -> IO ()-set_double gv d = withManagedPtr gv $ flip _set_double (realToFrac d)--get_double :: GValue -> IO Double-get_double gv = realToFrac <$> withManagedPtr gv _get_double--foreign import ccall unsafe "g_value_set_boolean" _set_boolean ::-    Ptr GValue -> CInt -> IO ()-foreign import ccall unsafe "g_value_get_boolean" _get_boolean ::-    Ptr GValue -> IO CInt--set_boolean :: GValue -> Bool -> IO ()-set_boolean gv b = withManagedPtr gv $ \ptr ->-                   _set_boolean ptr (fromIntegral $ fromEnum b)--get_boolean :: GValue -> IO Bool-get_boolean gv = withManagedPtr gv $ \ptr -> (/= 0) <$> _get_boolean ptr--foreign import ccall unsafe "g_value_set_gtype" _set_gtype ::-    Ptr GValue -> CGType -> IO ()-foreign import ccall unsafe "g_value_get_gtype" _get_gtype ::-    Ptr GValue -> IO CGType--set_gtype :: GValue -> GType -> IO ()-set_gtype gv (GType g) = withManagedPtr gv $ \ptr -> _set_gtype ptr g--get_gtype :: GValue -> IO GType-get_gtype gv = GType <$> withManagedPtr gv _get_gtype--foreign import ccall "g_value_set_object" _set_object ::-    Ptr GValue -> Ptr a -> IO ()-foreign import ccall "g_value_get_object" _get_object ::-    Ptr GValue -> IO (Ptr a)--set_object :: GObject a => GValue -> Ptr a -> IO ()-set_object gv o = withManagedPtr gv $ flip _set_object o--get_object :: GObject b => GValue -> IO (Ptr b)-get_object gv = withManagedPtr gv _get_object--foreign import ccall "g_value_set_boxed" _set_boxed ::-    Ptr GValue -> Ptr a -> IO ()-foreign import ccall "g_value_get_boxed" _get_boxed ::-    Ptr GValue -> IO (Ptr b)--set_boxed :: GValue -> Ptr a -> IO ()-set_boxed gv b = withManagedPtr gv $ flip _set_boxed b--get_boxed :: GValue -> IO (Ptr b)-get_boxed gv = withManagedPtr gv _get_boxed--foreign import ccall "g_value_set_variant" _set_variant ::-    Ptr GValue -> Ptr GVariant -> IO ()-foreign import ccall "g_value_get_variant" _get_variant ::-    Ptr GValue -> IO (Ptr GVariant)--set_variant :: GValue -> Ptr GVariant -> IO ()-set_variant gv v = withManagedPtr gv $ flip _set_variant v--get_variant :: GValue -> IO (Ptr GVariant)-get_variant gv = withManagedPtr gv _get_variant--foreign import ccall unsafe "g_value_set_enum" _set_enum ::-    Ptr GValue -> CUInt -> IO ()-foreign import ccall unsafe "g_value_get_enum" _get_enum ::-    Ptr GValue -> IO CUInt--set_enum :: GValue -> CUInt -> IO ()-set_enum gv e = withManagedPtr gv $ flip _set_enum e--get_enum :: GValue -> IO CUInt-get_enum gv = withManagedPtr gv _get_enum--foreign import ccall unsafe "g_value_set_flags" _set_flags ::-    Ptr GValue -> CUInt -> IO ()-foreign import ccall unsafe "g_value_get_flags" _get_flags ::-    Ptr GValue -> IO CUInt--set_flags :: GValue -> CUInt -> IO ()-set_flags gv f = withManagedPtr gv $ flip _set_flags f--get_flags :: GValue -> IO CUInt-get_flags gv = withManagedPtr gv _get_flags
− src/Data/GI/Base/GVariant.hsc
@@ -1,977 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE EmptyDataDecls #-}-{-|-This module contains some helper functions for dealing with GVariant-values. The simplest way of dealing with them is by using the-'IsGVariant' typeclass:--> str <- fromGVariant variant :: IO (Maybe Text)--assuming that the variant is expected to contain a-string in UTF8 encoding. The code becomes even shorter if the type-checker can determine the return type for you:---> readStringVariant :: GVariant -> IO Text-> readStringVariant variant =->   fromGVariant variant >>= \case->      Nothing  -> error "Variant was not a string"->      Just str -> return str--Alternatively, you can use manually the gvariantFrom* and-gvariantTo* family of functions.--}-module Data.GI.Base.GVariant-    ( IsGVariant(..)-    , IsGVariantBasicType--    , noGVariant--    , gvariantGetTypeString--    -- * Type wrappers-    -- | Some 'GVariant' types are isomorphic to Haskell types, but they-    -- carry some extra information. For example, there is a tuple-    -- singlet type, which is isomorphic to a single Haskell value-    -- with the added bit of information that it is wrapped in a tuple-    -- container. In order to use these values you can use the-    -- following wrappers, which allow the 'IsGVariant' instance to-    -- disambiguate the requested type properly.--    , GVariantSinglet(GVariantSinglet)-    , GVariantDictEntry(GVariantDictEntry)-    , GVariantHandle(GVariantHandle)-    , GVariantObjectPath-    , newGVariantObjectPath-    , gvariantObjectPathToText-    , GVariantSignature-    , newGVariantSignature-    , gvariantSignatureToText--    -- * Manual memory management--    , wrapGVariantPtr-    , newGVariantFromPtr-    , refGVariant-    , unrefGVariant--    -- * Manual conversions--    -- ** Basic types-    ---    -- | The use of these should be fairly self-explanatory. If you-    -- want to convert a Haskell type into a 'GVariant', use-    -- gvariantTo*. If you want to convert a 'GVariant' into a Haskell-    -- type, use gvariantFrom*. The conversion can fail if the-    -- 'GVariant' is not of the expected type (if you want to convert-    -- a 'GVariant' containing a 'Int16' into a 'Text' value, say), in-    -- which case 'Nothing' will be returned.-    , gvariantToBool-    , gvariantFromBool--    , gvariantToWord8-    , gvariantFromWord8--    , gvariantToInt16-    , gvariantFromInt16--    , gvariantToWord16-    , gvariantFromWord16--    , gvariantToInt32-    , gvariantFromInt32--    , gvariantToWord32-    , gvariantFromWord32--    , gvariantToInt64-    , gvariantFromInt64--    , gvariantToWord64-    , gvariantFromWord64--    , gvariantToHandle-    , gvariantFromHandle--    , gvariantToDouble-    , gvariantFromDouble--    , gvariantToText-    , gvariantFromText--    , gvariantToObjectPath-    , gvariantFromObjectPath--    , gvariantToSignature-    , gvariantFromSignature--    -- ** Container type conversions-    , gvariantToGVariant-    , gvariantFromGVariant--    , gvariantToBytestring-    , gvariantFromBytestring--    , gvariantFromMaybe-    , gvariantToMaybe--    , gvariantFromDictEntry-    , gvariantToDictEntry--    , gvariantFromMap-    , gvariantToMap--    , gvariantFromList-    , gvariantToList--    , gvariantFromTuple-    , gvariantToTuple-    ) where--#include <glib-object.h>--#if !MIN_VERSION_base(4,8,0)-import Control.Applicative ((<$>), (<*>))-#endif-import Control.Monad (when, void, (>=>))-import Control.Exception.Base (bracket)--import Data.Text (Text)-import Data.ByteString (ByteString)-import qualified Data.ByteString as B-import Data.Word-import Data.Int-import Data.Monoid ((<>))-import Data.Maybe (isJust, fromJust)-import qualified Data.Map as M--import System.IO.Unsafe (unsafePerformIO)-import Foreign.C-import Foreign.Ptr-import Foreign.ForeignPtr (withForeignPtr)--import Data.GI.Base.BasicTypes (GVariant(..))-import Data.GI.Base.BasicConversions-import Data.GI.Base.ManagedPtr (withManagedPtr, withManagedPtrList,-                                newManagedPtr)-import Data.GI.Base.Utils (freeMem)---- | An alias for @Nothing :: Maybe GVariant@ to save some typing.-noGVariant :: Maybe GVariant-noGVariant = Nothing---- | The typeclass for types that can be automatically marshalled into--- 'GVariant' using 'toGVariant' and 'fromGVariant'.-class IsGVariant a where-    -- | Convert a value of the given type into a GVariant.-    toGVariant   :: a -> IO GVariant-    -- | Try to decode a 'GVariant' into a target type. If the-    -- conversion fails we return 'Nothing'. The type that was-    -- expected can be obtained by calling 'toGVariantFormatString',-    -- and the actual type as understood by the 'GVariant' code can be-    -- obtained by calling 'gvariantToTypeString'.-    fromGVariant :: GVariant -> IO (Maybe a)-    -- | The expected format string for this type (the argument is-    -- ignored).-    toGVariantFormatString :: a -> Text---- Same as fromGVariant, for cases where we have checked that things--- have the right type in advance.-unsafeFromGVariant :: IsGVariant a => GVariant -> IO a-unsafeFromGVariant gv =-    fromGVariant gv >>= \case-                 Nothing -> error "Error decoding GVariant. This is a bug in haskell-gi, please report it."-                 Just value -> return value---- | The typeclass for basic type 'GVariant' types, i.e. those that--- are not containers.-class Ord a => IsGVariantBasicType a---- | Haskell has no notion of one element tuples, but GVariants do, so--- the following allows for marshalling one element tuples properly--- using 'fromGVariant' and 'toGVariant'. For instance, to construct a--- single element tuple containing a string, you could do------ > toGVariant (GVariantSinglet "Test")-newtype GVariantSinglet a = GVariantSinglet a-    deriving (Eq, Show)--data GVariantType--foreign import ccall "g_variant_type_new" g_variant_type_new ::-    CString -> IO (Ptr GVariantType)--foreign import ccall "g_variant_type_free" g_variant_type_free ::-    Ptr GVariantType -> IO ()--foreign import ccall "g_variant_is_of_type" g_variant_is_of_type ::-    Ptr GVariant -> Ptr GVariantType -> IO #{type gboolean}--withGVariantType :: Text -> (Ptr GVariantType -> IO a) -> IO a-withGVariantType text action = withTextCString text $ \textPtr ->-                               bracket (g_variant_type_new textPtr)-                                       g_variant_type_free-                                       action--gvariantIsOfType :: Text -> GVariant -> IO Bool-gvariantIsOfType typeString variant =-    withGVariantType typeString $-        \typePtr ->-            (toEnum . fromIntegral) <$> withManagedPtr variant-                                        (\vptr -> g_variant_is_of_type-                                                  vptr typePtr)--withExplicitType :: Text -> (Ptr GVariant -> IO a) -> GVariant -> IO (Maybe a)-withExplicitType format action variant = do-  check <- gvariantIsOfType format variant-  if check-  then Just <$> withManagedPtr variant action-  else return Nothing--withTypeCheck :: forall a. (IsGVariant a) =>-                 (Ptr GVariant -> IO a) -> GVariant -> IO (Maybe a)-withTypeCheck = withExplicitType $ toGVariantFormatString (undefined :: a)--foreign import ccall "g_variant_get_type_string" g_variant_get_type_string-    :: Ptr GVariant -> IO CString---- | Get the expected type of a 'GVariant', in 'GVariant'--- notation. See--- <https://developer.gnome.org/glib/stable/glib-GVariantType.html>--- for the meaning of the resulting format string.-gvariantGetTypeString :: GVariant -> IO Text-gvariantGetTypeString variant =-    withManagedPtr variant (g_variant_get_type_string >=> cstringToText)--foreign import ccall "g_variant_is_floating" g_variant_is_floating ::-    Ptr GVariant -> IO CInt-foreign import ccall "g_variant_ref_sink" g_variant_ref_sink ::-    Ptr GVariant -> IO (Ptr GVariant)-foreign import ccall "g_variant_ref" g_variant_ref ::-    Ptr GVariant -> IO (Ptr GVariant)-foreign import ccall "g_variant_unref" g_variant_unref ::-    Ptr GVariant -> IO ()-foreign import ccall "&g_variant_unref" ptr_to_g_variant_unref ::-    FunPtr (Ptr GVariant -> IO ())---- | Take ownership of a passed in 'Ptr' (typically created just for--- us, so if it is floating we sink it).-wrapGVariantPtr :: Ptr GVariant -> IO GVariant-wrapGVariantPtr ptr = do-  floating <- g_variant_is_floating ptr-  when (floating /= 0) $ void $ g_variant_ref_sink ptr-  fPtr <- newManagedPtr ptr_to_g_variant_unref ptr-  return $! GVariant fPtr---- | Construct a Haskell wrapper for the given 'GVariant', without--- assuming ownership.-newGVariantFromPtr :: Ptr GVariant -> IO GVariant-newGVariantFromPtr ptr = do-  fPtr <- g_variant_ref ptr >>= newManagedPtr ptr_to_g_variant_unref-  return $! GVariant fPtr---- | Add a reference to the given 'GVariant'.-refGVariant :: GVariant -> IO (Ptr GVariant)-refGVariant (GVariant fptr) = withForeignPtr fptr g_variant_ref---- | Remove a reference to the given 'GVariant'.-unrefGVariant :: GVariant -> IO ()-unrefGVariant (GVariant fptr) = withForeignPtr fptr g_variant_unref--instance IsGVariant Bool where-    toGVariant = gvariantFromBool-    fromGVariant = gvariantToBool-    toGVariantFormatString _ = "b"-instance IsGVariantBasicType Bool--foreign import ccall "g_variant_new_boolean" new_bool-    :: #{type gboolean} -> IO (Ptr GVariant)--gvariantFromBool :: Bool -> IO GVariant-gvariantFromBool = (new_bool . fromIntegral . fromEnum) >=> wrapGVariantPtr--foreign import ccall "g_variant_get_boolean" get_bool-    :: Ptr GVariant -> IO #{type gboolean}--gvariantToBool :: GVariant -> IO (Maybe Bool)-gvariantToBool = withTypeCheck $ get_bool >=> (return . toEnum . fromIntegral)--instance IsGVariant Word8 where-    toGVariant = gvariantFromWord8-    fromGVariant = gvariantToWord8-    toGVariantFormatString _ = "y"-instance IsGVariantBasicType Word8--foreign import ccall "g_variant_new_byte" new_byte-    :: #{type guchar} -> IO (Ptr GVariant)--gvariantFromWord8 :: Word8 -> IO GVariant-gvariantFromWord8 = (new_byte . fromIntegral) >=> wrapGVariantPtr--foreign import ccall "g_variant_get_byte" get_byte-    :: Ptr GVariant -> IO #{type guchar}--gvariantToWord8 :: GVariant -> IO (Maybe Word8)-gvariantToWord8 = withTypeCheck $ get_byte >=> (return . fromIntegral)--instance IsGVariant Int16 where-    toGVariant = gvariantFromInt16-    fromGVariant = gvariantToInt16-    toGVariantFormatString _ = "n"-instance IsGVariantBasicType Int16--foreign import ccall "g_variant_new_int16" new_int16-    :: #{type gint16} -> IO (Ptr GVariant)--gvariantFromInt16 :: Int16 -> IO GVariant-gvariantFromInt16 = (new_int16 . fromIntegral) >=> wrapGVariantPtr--foreign import ccall "g_variant_get_int16" get_int16-    :: Ptr GVariant -> IO #{type gint16}--gvariantToInt16 :: GVariant -> IO (Maybe Int16)-gvariantToInt16 = withTypeCheck $ get_int16 >=> (return . fromIntegral)--instance IsGVariant Word16 where-    toGVariant = gvariantFromWord16-    fromGVariant = gvariantToWord16-    toGVariantFormatString _ = "q"-instance IsGVariantBasicType Word16--foreign import ccall "g_variant_new_uint16" new_uint16-    :: #{type guint16} -> IO (Ptr GVariant)--gvariantFromWord16 :: Word16 -> IO GVariant-gvariantFromWord16 = new_uint16 . fromIntegral >=> wrapGVariantPtr--foreign import ccall "g_variant_get_uint16" get_uint16-    :: Ptr GVariant -> IO #{type guint16}--gvariantToWord16 :: GVariant -> IO (Maybe Word16)-gvariantToWord16 = withTypeCheck $ get_uint16 >=> (return . fromIntegral)--instance IsGVariant Int32 where-    toGVariant = gvariantFromInt32-    fromGVariant = gvariantToInt32-    toGVariantFormatString _ = "i"-instance IsGVariantBasicType Int32--foreign import ccall "g_variant_new_int32" new_int32-    :: #{type gint16} -> IO (Ptr GVariant)--gvariantFromInt32 :: Int32 -> IO GVariant-gvariantFromInt32 = (new_int32 . fromIntegral) >=> wrapGVariantPtr--foreign import ccall "g_variant_get_int32" get_int32-    :: Ptr GVariant -> IO #{type gint32}--gvariantToInt32 :: GVariant -> IO (Maybe Int32)-gvariantToInt32 = withTypeCheck $ get_int32 >=> (return . fromIntegral)--instance IsGVariant Word32 where-    toGVariant = gvariantFromWord32-    fromGVariant = gvariantToWord32-    toGVariantFormatString _ = "u"-instance IsGVariantBasicType Word32--foreign import ccall "g_variant_new_uint32" new_uint32-    :: #{type guint32} -> IO (Ptr GVariant)--gvariantFromWord32 :: Word32 -> IO GVariant-gvariantFromWord32 = (new_uint32 . fromIntegral) >=> wrapGVariantPtr--foreign import ccall "g_variant_get_uint32" get_uint32-    :: Ptr GVariant -> IO #{type guint32}--gvariantToWord32 :: GVariant -> IO (Maybe Word32)-gvariantToWord32 = withTypeCheck $ get_uint32 >=> (return . fromIntegral)--instance IsGVariant Int64 where-    toGVariant = gvariantFromInt64-    fromGVariant = gvariantToInt64-    toGVariantFormatString _ = "x"-instance IsGVariantBasicType Int64--foreign import ccall "g_variant_new_int64" new_int64-    :: #{type gint64} -> IO (Ptr GVariant)--gvariantFromInt64 :: Int64 -> IO GVariant-gvariantFromInt64 = (new_int64 . fromIntegral) >=> wrapGVariantPtr--foreign import ccall "g_variant_get_int64" get_int64-    :: Ptr GVariant -> IO #{type gint64}--gvariantToInt64 :: GVariant -> IO (Maybe Int64)-gvariantToInt64 = withTypeCheck $ get_int64 >=> (return . fromIntegral)--instance IsGVariant Word64 where-    toGVariant = gvariantFromWord64-    fromGVariant = gvariantToWord64-    toGVariantFormatString _ = "t"-instance IsGVariantBasicType Word64--foreign import ccall "g_variant_new_uint64" new_uint64-    :: #{type guint64} -> IO (Ptr GVariant)--gvariantFromWord64 :: Word64 -> IO GVariant-gvariantFromWord64 = (new_uint64 . fromIntegral) >=> wrapGVariantPtr--foreign import ccall "g_variant_get_uint64" get_uint64-    :: Ptr GVariant -> IO #{type guint64}--gvariantToWord64 :: GVariant -> IO (Maybe Word64)-gvariantToWord64 = withTypeCheck $ get_uint64 >=> (return . fromIntegral)--newtype GVariantHandle = GVariantHandle Int32-    deriving (Eq, Ord, Show)--instance IsGVariant GVariantHandle where-    toGVariant (GVariantHandle h) = gvariantFromHandle h-    fromGVariant = gvariantToHandle >=> (return . (GVariantHandle <$>))-    toGVariantFormatString _ = "h"-instance IsGVariantBasicType GVariantHandle--foreign import ccall "g_variant_new_handle" new_handle-    :: #{type gint32} -> IO (Ptr GVariant)---- | Convert a DBus handle (an 'Int32') into a 'GVariant'.-gvariantFromHandle :: Int32 -> IO GVariant-gvariantFromHandle h = (new_handle . fromIntegral) h >>= wrapGVariantPtr--foreign import ccall "g_variant_get_handle" get_handle-    :: Ptr GVariant -> IO #{type gint32}---- | Extract the DBus handle (an 'Int32') inside a 'GVariant'.-gvariantToHandle :: GVariant -> IO (Maybe Int32)-gvariantToHandle =-  withExplicitType (toGVariantFormatString (undefined :: GVariantHandle)) $-                   get_handle >=> (return . fromIntegral)--instance IsGVariant Double where-    toGVariant = gvariantFromDouble-    fromGVariant = gvariantToDouble-    toGVariantFormatString _ = "d"-instance IsGVariantBasicType Double--foreign import ccall "g_variant_new_double" new_double-    :: #{type gdouble} -> IO (Ptr GVariant)--gvariantFromDouble :: Double -> IO GVariant-gvariantFromDouble = (new_double . realToFrac) >=> wrapGVariantPtr--foreign import ccall "g_variant_get_double" get_double-    :: Ptr GVariant -> IO #{type gdouble}--gvariantToDouble :: GVariant -> IO (Maybe Double)-gvariantToDouble = withTypeCheck $ get_double >=> (return . realToFrac)--instance IsGVariant Text where-    toGVariant = gvariantFromText-    fromGVariant = gvariantToText-    toGVariantFormatString _ = "s"-instance IsGVariantBasicType Text--foreign import ccall "g_variant_get_string" _get_string-    :: Ptr GVariant -> Ptr #{type gsize} -> IO CString--get_string :: Ptr GVariant -> IO CString-get_string v = _get_string v nullPtr---- | Decode an UTF-8 encoded string 'GVariant' into 'Text'.-gvariantToText :: GVariant -> IO (Maybe Text)-gvariantToText = withTypeCheck $ get_string >=> cstringToText--foreign import ccall "g_variant_new_take_string" take_string-    :: CString -> IO (Ptr GVariant)---- | Encode a 'Text' into an UTF-8 encoded string 'GVariant'.-gvariantFromText :: Text -> IO GVariant-gvariantFromText = textToCString >=> take_string >=> wrapGVariantPtr--foreign import ccall "g_variant_is_object_path" g_variant_is_object_path ::-    CString -> IO #{type gboolean}---- | An object representing a DBus object path, which is a particular--- type of 'GVariant' too. (Just a string with some specific--- requirements.) In order to construct/deconstruct a--- 'GVariantObjectPath' one can use 'newGVariantObjectPath'--- and 'gvariantObjectPathToText'.-newtype GVariantObjectPath = GVariantObjectPath Text-    deriving (Ord, Eq, Show)---- | Try to construct a DBus object path. If the passed string is not--- a valid object path 'Nothing' will be returned.-newGVariantObjectPath :: Text -> Maybe GVariantObjectPath-newGVariantObjectPath p = unsafePerformIO $-   withTextCString p $ \cstr -> do-     isObjectPath <- toEnum . fromIntegral <$> g_variant_is_object_path cstr-     if isObjectPath-     then return $ Just (GVariantObjectPath p)-     else return Nothing---- | Return the 'Text' representation of a 'GVariantObjectPath'.-gvariantObjectPathToText :: GVariantObjectPath -> Text-gvariantObjectPathToText (GVariantObjectPath p) = p--instance IsGVariant GVariantObjectPath where-    toGVariant = gvariantFromObjectPath-    fromGVariant = gvariantToObjectPath >=> return . (GVariantObjectPath <$>)-    toGVariantFormatString _ = "o"-instance IsGVariantBasicType GVariantObjectPath--foreign import ccall "g_variant_new_object_path" new_object_path-    :: CString -> IO (Ptr GVariant)---- | Construct a 'GVariant' containing an object path. In order to--- build a 'GVariantObjectPath' value see 'newGVariantObjectPath'.-gvariantFromObjectPath :: GVariantObjectPath -> IO GVariant-gvariantFromObjectPath (GVariantObjectPath p) =-    withTextCString p $ new_object_path >=> wrapGVariantPtr---- | Extract a 'GVariantObjectPath' from a 'GVariant', represented as--- its underlying 'Text' representation.-gvariantToObjectPath :: GVariant -> IO (Maybe Text)-gvariantToObjectPath =-    withExplicitType (toGVariantFormatString (undefined :: GVariantObjectPath))-                         (get_string >=> cstringToText)--foreign import ccall "g_variant_is_signature" g_variant_is_signature ::-    CString -> IO #{type gboolean}---- | An object representing a DBus signature, which is a particular--- type of 'GVariant' too. (Just a string with some specific--- requirements.) In order to construct/deconstruct a--- 'GVariantSignature' one can use 'newGVariantSignature' and--- 'gvariantSignatureToText'.-newtype GVariantSignature = GVariantSignature Text-    deriving (Ord, Eq, Show)---- | Try to construct a DBus object path. If the passed string is not--- a valid DBus signature 'Nothing' will be returned.-newGVariantSignature :: Text -> Maybe GVariantSignature-newGVariantSignature p = unsafePerformIO $-   withTextCString p $ \cstr -> do-     isSignature <- toEnum . fromIntegral <$> g_variant_is_signature cstr-     if isSignature-     then return $ Just (GVariantSignature p)-     else return Nothing---- | Return the 'Text' representation of a 'GVariantSignature'.-gvariantSignatureToText :: GVariantSignature -> Text-gvariantSignatureToText (GVariantSignature p) = p--instance IsGVariant GVariantSignature where-    toGVariant = gvariantFromSignature-    fromGVariant = gvariantToSignature >=> return . (GVariantSignature <$>)-    toGVariantFormatString _ = "g"-instance IsGVariantBasicType GVariantSignature--foreign import ccall "g_variant_new_signature" new_signature-    :: CString -> IO (Ptr GVariant)---- | Construct a 'GVariant' containing an DBus signature. In order to--- build a 'GVariantSignature' value see 'newGVariantSignature'.-gvariantFromSignature :: GVariantSignature -> IO GVariant-gvariantFromSignature (GVariantSignature p) =-    withTextCString p $ new_signature >=> wrapGVariantPtr---- | Extract a 'GVariantSignature' from a 'GVariant', represented as--- 'Text'.-gvariantToSignature :: GVariant -> IO (Maybe Text)-gvariantToSignature =-    withExplicitType (toGVariantFormatString (undefined :: GVariantSignature))-                         $ get_string >=> cstringToText--instance IsGVariant GVariant where-    toGVariant = gvariantFromGVariant-    fromGVariant = gvariantToGVariant-    toGVariantFormatString _ = "v"--foreign import ccall "g_variant_new_variant" new_variant-    :: Ptr GVariant -> IO (Ptr GVariant)---- | Box a 'GVariant' inside another 'GVariant'.-gvariantFromGVariant :: GVariant -> IO GVariant-gvariantFromGVariant v = withManagedPtr v $ new_variant >=> wrapGVariantPtr--foreign import ccall "g_variant_get_variant" get_variant-    :: Ptr GVariant -> IO (Ptr GVariant)---- | Unbox a 'GVariant' contained inside another 'GVariant'.-gvariantToGVariant :: GVariant -> IO (Maybe GVariant)-gvariantToGVariant = withTypeCheck $ get_variant >=> wrapGVariantPtr--instance IsGVariant ByteString where-    toGVariant = gvariantFromBytestring-    fromGVariant = gvariantToBytestring-    toGVariantFormatString _ = "ay"--foreign import ccall "g_variant_get_bytestring" get_bytestring-    :: Ptr GVariant -> IO CString---- | Extract a zero terminated list of bytes into a 'ByteString'.-gvariantToBytestring :: GVariant -> IO (Maybe ByteString)-gvariantToBytestring = withTypeCheck (get_bytestring >=> cstringToByteString)--foreign import ccall "g_variant_new_bytestring" new_bytestring-    :: CString -> IO (Ptr GVariant)---- | Encode a 'ByteString' into a list of bytes 'GVariant'.-gvariantFromBytestring :: ByteString -> IO GVariant-gvariantFromBytestring bs = wrapGVariantPtr =<<-                              B.useAsCString bs new_bytestring---foreign import ccall "g_variant_n_children" g_variant_n_children-    :: Ptr GVariant -> IO #{type gsize}--foreign import ccall "g_variant_get_child_value" g_variant_get_child_value-    :: Ptr GVariant -> #{type gsize} -> IO (Ptr GVariant)---- No type checking is done here, it is assumed that the caller knows--- that the passed variant is indeed of a container type.-gvariant_get_children :: (Ptr GVariant) -> IO [GVariant]-gvariant_get_children vptr = do-      n_children <- g_variant_n_children vptr-      mapM ((g_variant_get_child_value vptr) >=> wrapGVariantPtr)-               [0..(n_children-1)]--instance IsGVariant a => IsGVariant (Maybe a) where-    toGVariant   = gvariantFromMaybe-    fromGVariant = gvariantToMaybe-    toGVariantFormatString _ = "m" <> toGVariantFormatString (undefined :: a)--foreign import ccall "g_variant_new_maybe" g_variant_new_maybe ::-    Ptr GVariantType -> Ptr GVariant -> IO (Ptr GVariant)---- | Convert a 'Maybe' value into a corresponding 'GVariant' of maybe--- type.-gvariantFromMaybe :: forall a. IsGVariant a => Maybe a -> IO GVariant-gvariantFromMaybe m = do-  let fmt = toGVariantFormatString (undefined :: a)-  withGVariantType fmt $ \tPtr ->-      case m of-        Just child -> do-               childVariant <- toGVariant child-               withManagedPtr childVariant-                      (g_variant_new_maybe tPtr >=> wrapGVariantPtr)-        Nothing -> g_variant_new_maybe tPtr nullPtr >>= wrapGVariantPtr---- | Try to decode a maybe 'GVariant' into the corresponding 'Maybe'--- type. If the conversion is successful this returns @Just x@, where--- @x@ itself is of 'Maybe' type. So, in particular, @Just Nothing@--- indicates a successful call, and means that the GVariant of maybe--- type was empty.-gvariantToMaybe :: forall a. IsGVariant a => GVariant -> IO (Maybe (Maybe a))-gvariantToMaybe v = do-  let fmt = toGVariantFormatString (undefined :: Maybe a)-  withExplicitType fmt gvariant_get_children v >>=-   \case-     Just [] -> return (Just Nothing)-     Just [child] -> fromGVariant child >>=-                     \case-                       Nothing -> return Nothing-                       Just result -> return (Just (Just result))-     Just _ -> error "gvariantToMaybe :: the impossible happened, this is a bug."-     Nothing -> return Nothing---- | A DictEntry 'GVariant' is isomorphic to a two-tuple. Wrapping the--- values into a 'GVariantDictentry' allows the 'IsGVariant' instance--- to do the right thing.-data GVariantDictEntry key value = GVariantDictEntry key value-                                   deriving (Eq, Show)--instance (IsGVariant a, IsGVariantBasicType a, IsGVariant b) =>-    IsGVariant (GVariantDictEntry a b) where-        toGVariant (GVariantDictEntry key value) =-            gvariantFromDictEntry key value-        fromGVariant gv =-            ((uncurry GVariantDictEntry) <$>) <$> gvariantToDictEntry gv-        toGVariantFormatString _ = "{"-                                   <> toGVariantFormatString (undefined :: a)-                                   <> toGVariantFormatString (undefined :: b)-                                   <> "}"--foreign import ccall "g_variant_new_dict_entry" g_variant_new_dict_entry ::-    Ptr GVariant -> Ptr GVariant -> IO (Ptr GVariant)---- | Construct a 'GVariant' of type DictEntry from the given 'key' and--- 'value'. The key must be a basic 'GVariant' type, i.e. not a--- container. This is determined by whether it belongs to the--- 'IsGVariantBasicType' typeclass. On the other hand 'value' is an--- arbitrary 'GVariant', and in particular it can be a container type.-gvariantFromDictEntry :: (IsGVariant key, IsGVariantBasicType key,-                          IsGVariant value) =>-                         key -> value -> IO GVariant-gvariantFromDictEntry key value = do-  keyVar <- toGVariant key-  valueVar <- toGVariant value-  withManagedPtr keyVar $ \keyPtr ->-      withManagedPtr valueVar $ \valuePtr ->-          g_variant_new_dict_entry keyPtr valuePtr >>= wrapGVariantPtr---- | Unpack a DictEntry variant into 'key' and 'value', which are--- returned as a two element tuple in case of success.-gvariantToDictEntry :: forall key value.-                       (IsGVariant key, IsGVariantBasicType key,-                        IsGVariant value) =>-                       GVariant -> IO (Maybe (key, value))-gvariantToDictEntry =-    withExplicitType fmt $ \varPtr -> do-      [key, value] <- gvariant_get_children varPtr-      (,) <$> unsafeFromGVariant key <*> unsafeFromGVariant value-    where-      fmt = toGVariantFormatString (undefined :: GVariantDictEntry key value)--instance (IsGVariant a, IsGVariantBasicType a, IsGVariant b) =>-    IsGVariant (M.Map a b) where-        toGVariant = gvariantFromMap-        fromGVariant = gvariantToMap-        toGVariantFormatString _ = "a{"-                                   <> toGVariantFormatString (undefined :: a)-                                   <> toGVariantFormatString (undefined :: b)-                                   <> "}"---- | Pack a 'Map' into a 'GVariant' for dictionary type, which is just--- an array of 'GVariantDictEntry'.-gvariantFromMap :: (IsGVariant key, IsGVariantBasicType key,-                    IsGVariant value) =>-                   M.Map key value -> IO GVariant-gvariantFromMap m = gvariantFromList $-                       map (uncurry GVariantDictEntry) (M.toList m)---- | Unpack a 'GVariant' into a 'M.Map'. Notice that this assumes that--- all the elements in the 'GVariant' array of 'GVariantDictEntry' are--- of the same type, which is not necessary for a generic 'GVariant',--- so this is somewhat restrictive. For the general case it is--- necessary to use 'gvariantToList' plus 'gvariantToDictEntry'--- directly.-gvariantToMap :: forall key value.-                 (IsGVariant key, IsGVariantBasicType key,-                  IsGVariant value) =>-                 GVariant -> IO (Maybe (M.Map key value))-gvariantToMap = gvariantToList >=> (return . (fromDictEntryList <$>))-    where fromDictEntryList :: [GVariantDictEntry key value] ->-                               M.Map key value-          fromDictEntryList = M.fromList . (map tuplefy)-          tuplefy :: GVariantDictEntry key value -> (key, value)-          tuplefy (GVariantDictEntry key value) = (key, value)--instance IsGVariant a => IsGVariant [a] where-    toGVariant   = gvariantFromList-    fromGVariant = gvariantToList-    toGVariantFormatString _ = "a" <> toGVariantFormatString (undefined :: a)--foreign import ccall "g_variant_new_array" g_variant_new_array ::-    Ptr GVariantType -> Ptr (Ptr GVariant) -> #{type gsize} -> IO (Ptr GVariant)---- | Given a list of elements construct a 'GVariant' array containing--- them.-gvariantFromList :: forall a. IsGVariant a => [a] -> IO GVariant-gvariantFromList children = do-  let fmt = toGVariantFormatString (undefined :: a)-  mapM toGVariant children >>= \childVariants ->-      withManagedPtrList childVariants $ \childrenPtrs -> do-          withGVariantType fmt $ \childType -> do-             packed <- packPtrArray childrenPtrs-             result <- g_variant_new_array childType packed-                            (fromIntegral $ length children)-             freeMem packed-             wrapGVariantPtr result---- | Unpack a 'GVariant' array into its elements.-gvariantToList :: forall a. IsGVariant a => GVariant -> IO (Maybe [a])-gvariantToList = withExplicitType (toGVariantFormatString (undefined :: [a]))-                 (gvariant_get_children >=> mapM unsafeFromGVariant)--foreign import ccall "g_variant_new_tuple" g_variant_new_tuple-        :: Ptr (Ptr GVariant) -> #{type gsize} -> IO (Ptr GVariant)---- | Given a list of 'GVariant', construct a 'GVariant' tuple--- containing the elements in the list.-gvariantFromTuple :: [GVariant] -> IO GVariant-gvariantFromTuple children =-    withManagedPtrList children $ \childrenPtrs -> do-      packed <- packPtrArray childrenPtrs-      result <- g_variant_new_tuple packed (fromIntegral $ length children)-      freeMem packed-      wrapGVariantPtr result---- | Extract the children of a 'GVariant' tuple into a list.-gvariantToTuple :: GVariant -> IO (Maybe [GVariant])-gvariantToTuple = withExplicitType "r" gvariant_get_children---- | The empty tuple GVariant, mostly useful for type checking.-instance IsGVariant () where-    toGVariant _ = gvariantFromTuple []-    fromGVariant = withTypeCheck (const $ return ())-    toGVariantFormatString _ = "()"---- | One element tuples.-instance IsGVariant a => IsGVariant (GVariantSinglet a) where-    toGVariant (GVariantSinglet s) = gvariantFromSinglet s-    fromGVariant = gvariantToSinglet >=> return . (GVariantSinglet <$>)-    toGVariantFormatString _ = "("-                               <> toGVariantFormatString (undefined :: a)-                               <> ")"--gvariantFromSinglet :: IsGVariant a => a -> IO GVariant-gvariantFromSinglet s = do-  sv <- toGVariant s-  gvariantFromTuple [sv]--gvariantToSinglet :: forall a. IsGVariant a => GVariant -> IO (Maybe a)-gvariantToSinglet = withExplicitType fmt-                    (gvariant_get_children-                     >=> return . head-                     >=> unsafeFromGVariant)-    where fmt = toGVariantFormatString (undefined :: GVariantSinglet a)--instance (IsGVariant a, IsGVariant b) => IsGVariant (a,b) where-    toGVariant = gvariantFromTwoTuple-    fromGVariant = gvariantToTwoTuple-    toGVariantFormatString _ = "("-                               <> toGVariantFormatString (undefined :: a)-                               <> toGVariantFormatString (undefined :: b)-                               <> ")"--gvariantFromTwoTuple :: (IsGVariant a, IsGVariant b) =>-                        (a,b) -> IO GVariant-gvariantFromTwoTuple (a, b) = do-  va <- toGVariant a-  vb <- toGVariant b-  gvariantFromTuple [va, vb]--gvariantToTwoTuple :: forall a b. (IsGVariant a, IsGVariant b) =>-                      GVariant -> IO (Maybe (a,b))-gvariantToTwoTuple variant = do-  let expectedType = toGVariantFormatString (undefined :: (a,b))-  maybeChildren <- withExplicitType expectedType gvariant_get_children variant-  if isJust maybeChildren-  then do-    let (Just [a1,a2]) = maybeChildren-    (ma1, ma2) <- (,) <$> fromGVariant a1 <*> fromGVariant a2-    return $ if isJust ma1 && isJust ma2-             then Just (fromJust ma1, fromJust ma2)-             else Nothing-  else return Nothing--instance (IsGVariant a, IsGVariant b, IsGVariant c) => IsGVariant (a,b,c) where-    toGVariant = gvariantFromThreeTuple-    fromGVariant = gvariantToThreeTuple-    toGVariantFormatString _ = "("-                               <> toGVariantFormatString (undefined :: a)-                               <> toGVariantFormatString (undefined :: b)-                               <> toGVariantFormatString (undefined :: c)-                               <> ")"--gvariantFromThreeTuple :: (IsGVariant a, IsGVariant b, IsGVariant c) =>-                        (a,b,c) -> IO GVariant-gvariantFromThreeTuple (a, b, c) = do-  va <- toGVariant a-  vb <- toGVariant b-  vc <- toGVariant c-  gvariantFromTuple [va, vb, vc]--gvariantToThreeTuple :: forall a b c. (IsGVariant a, IsGVariant b,-                                                  IsGVariant c) =>-                      GVariant -> IO (Maybe (a,b,c))-gvariantToThreeTuple variant = do-  let expectedType = toGVariantFormatString (undefined :: (a,b,c))-  maybeChildren <- withExplicitType expectedType gvariant_get_children variant-  if isJust maybeChildren-  then do-    let (Just [a1,a2,a3]) = maybeChildren-    (ma1, ma2, ma3) <- (,,) <$> fromGVariant a1-                            <*> fromGVariant a2-                            <*> fromGVariant a3-    return $ if isJust ma1 && isJust ma2 && isJust ma3-             then Just (fromJust ma1, fromJust ma2, fromJust ma3)-             else Nothing-  else return Nothing--instance (IsGVariant a, IsGVariant b, IsGVariant c, IsGVariant d) =>-    IsGVariant (a,b,c,d) where-    toGVariant = gvariantFromFourTuple-    fromGVariant = gvariantToFourTuple-    toGVariantFormatString _ = "("-                               <> toGVariantFormatString (undefined :: a)-                               <> toGVariantFormatString (undefined :: b)-                               <> toGVariantFormatString (undefined :: c)-                               <> toGVariantFormatString (undefined :: d)-                               <> ")"--gvariantFromFourTuple :: (IsGVariant a, IsGVariant b, IsGVariant c,-                          IsGVariant d) => (a,b,c,d) -> IO GVariant-gvariantFromFourTuple (a, b, c, d) = do-  va <- toGVariant a-  vb <- toGVariant b-  vc <- toGVariant c-  vd <- toGVariant d-  gvariantFromTuple [va, vb, vc, vd]--gvariantToFourTuple :: forall a b c d. (IsGVariant a, IsGVariant b,-                                        IsGVariant c, IsGVariant d) =>-                      GVariant -> IO (Maybe (a,b,c,d))-gvariantToFourTuple variant = do-  let expectedType = toGVariantFormatString (undefined :: (a,b,c,d))-  maybeChildren <- withExplicitType expectedType gvariant_get_children variant-  if isJust maybeChildren-  then do-    let (Just [a1,a2,a3,a4]) = maybeChildren-    (ma1, ma2, ma3,ma4) <- (,,,) <$> fromGVariant a1-                                 <*> fromGVariant a2-                                 <*> fromGVariant a3-                                 <*> fromGVariant a4-    return $ if isJust ma1 && isJust ma2 && isJust ma3 && isJust ma4-             then Just (fromJust ma1, fromJust ma2, fromJust ma3, fromJust ma4)-             else Nothing-  else return Nothing--instance (IsGVariant a, IsGVariant b, IsGVariant c, IsGVariant d, IsGVariant e)-    => IsGVariant (a,b,c,d,e) where-    toGVariant = gvariantFromFiveTuple-    fromGVariant = gvariantToFiveTuple-    toGVariantFormatString _ = "("-                               <> toGVariantFormatString (undefined :: a)-                               <> toGVariantFormatString (undefined :: b)-                               <> toGVariantFormatString (undefined :: c)-                               <> toGVariantFormatString (undefined :: d)-                               <> toGVariantFormatString (undefined :: e)-                               <> ")"--gvariantFromFiveTuple :: (IsGVariant a, IsGVariant b, IsGVariant c,-                          IsGVariant d, IsGVariant e) =>-                         (a,b,c,d,e) -> IO GVariant-gvariantFromFiveTuple (a, b, c, d, e) = do-  va <- toGVariant a-  vb <- toGVariant b-  vc <- toGVariant c-  vd <- toGVariant d-  ve <- toGVariant e-  gvariantFromTuple [va, vb, vc, vd, ve]--gvariantToFiveTuple :: forall a b c d e.-                       (IsGVariant a, IsGVariant b, IsGVariant c,-                        IsGVariant d, IsGVariant e) =>-                      GVariant -> IO (Maybe (a,b,c,d,e))-gvariantToFiveTuple variant = do-  let expectedType = toGVariantFormatString (undefined :: (a,b,c,d,e))-  maybeChildren <- withExplicitType expectedType gvariant_get_children variant-  if isJust maybeChildren-  then do-    let (Just [a1,a2,a3,a4,a5]) = maybeChildren-    (ma1, ma2, ma3, ma4, ma5) <- (,,,,) <$> fromGVariant a1-                                        <*> fromGVariant a2-                                        <*> fromGVariant a3-                                        <*> fromGVariant a4-                                        <*> fromGVariant a5-    return $ if isJust ma1 && isJust ma2 && isJust ma3 &&-                              isJust ma4 && isJust ma5-             then Just (fromJust ma1, fromJust ma2, fromJust ma3,-                        fromJust ma4, fromJust ma5)-             else Nothing-  else return Nothing
− src/Data/GI/Base/ManagedPtr.hs
@@ -1,290 +0,0 @@-{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}--- For HasCallStack compatibility-{-# LANGUAGE ImplicitParams, KindSignatures, ConstraintKinds #-}---- | We wrap most objects in a "managed pointer", which is simply a--- newtype for a 'ForeignPtr' of the appropriate type:------ > newtype Foo = Foo (ForeignPtr Foo)------ Notice that types of this form are instances of--- 'ForeignPtrNewtype'. The newtype is useful in order to make the--- newtype an instance of different typeclasses. The routines in this--- module deal with the memory management of such managed pointers.--module Data.GI.Base.ManagedPtr-    (-    -- * Managed pointers-      newManagedPtr-    , withManagedPtr-    , maybeWithManagedPtr-    , withManagedPtrList-    , unsafeManagedPtrGetPtr-    , unsafeManagedPtrCastPtr-    , touchManagedPtr--    -- * Safe casting-    , castTo-    , unsafeCastTo--    -- * Wrappers-    , newObject-    , wrapObject-    , refObject-    , unrefObject-    , newBoxed-    , wrapBoxed-    , copyBoxed-    , copyBoxedPtr-    , freeBoxed-    , wrapPtr-    , newPtr-    , copyPtr-    ) where--#if !MIN_VERSION_base(4,8,0)-import Control.Applicative ((<$>))-#endif-import Control.Monad (when, void)--import Data.Coerce (coerce)--import Foreign.C (CInt(..))-import Foreign.Ptr (Ptr, FunPtr, castPtr, nullPtr)-import Foreign.ForeignPtr (ForeignPtr, FinalizerPtr,-                           touchForeignPtr, newForeignPtr_)-import qualified Foreign.Concurrent as FC-import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)--import Data.GI.Base.BasicTypes-import Data.GI.Base.Utils--#if MIN_VERSION_base(4,9,0)-import GHC.Stack (HasCallStack)-#elif MIN_VERSION_base(4,8,1)-import GHC.Stack (CallStack)-import GHC.Exts (Constraint)-type HasCallStack = ((?callStack :: CallStack) :: Constraint)-#else-import GHC.Exts (Constraint)-type HasCallStack = (() :: Constraint)-#endif--foreign import ccall "dynamic"-   mkFinalizer :: FinalizerPtr a -> Ptr a -> IO ()---- | A thin wrapper over `Foreign.Concurrent.newForeignPtr`.-newManagedPtr :: FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)-newManagedPtr finalizer ptr = do-  FC.newForeignPtr ptr (mkFinalizer finalizer ptr)---- | Perform an IO action on the 'Ptr' inside a managed pointer.-withManagedPtr :: ForeignPtrNewtype a => a -> (Ptr a -> IO c) -> IO c-withManagedPtr managed action = do-  let ptr = unsafeManagedPtrGetPtr managed-  result <- action ptr-  touchManagedPtr managed-  return result---- | Like `withManagedPtr`, but accepts a `Maybe` type. If the passed--- value is `Nothing` the inner action will be executed with a--- `nullPtr` argument.-maybeWithManagedPtr :: ForeignPtrNewtype a => Maybe a -> (Ptr a -> IO c) -> IO c-maybeWithManagedPtr Nothing action = action nullPtr-maybeWithManagedPtr (Just managed) action = do-  let ptr = unsafeManagedPtrGetPtr managed-  result <- action ptr-  touchManagedPtr managed-  return result---- | Perform an IO action taking a list of 'Ptr' on a list of managed--- pointers.-withManagedPtrList :: ForeignPtrNewtype a => [a] -> ([Ptr a] -> IO c) -> IO c-withManagedPtrList managedList action = do-  let ptrs = map unsafeManagedPtrGetPtr managedList-  result <- action ptrs-  mapM_ touchManagedPtr managedList-  return result---- | Return the 'Ptr' in a given managed pointer. As the name says,--- this is potentially unsafe: the given 'Ptr' may only be used--- /before/ a call to 'touchManagedPtr'. This function is of most--- interest to the autogenerated bindings, for hand-written code--- 'withManagedPtr' is almost always a better choice.-unsafeManagedPtrGetPtr :: ForeignPtrNewtype a => a -> Ptr a-unsafeManagedPtrGetPtr = unsafeManagedPtrCastPtr---- | Same as 'unsafeManagedPtrGetPtr', but is polymorphic on the--- return type.-unsafeManagedPtrCastPtr :: forall a b. ForeignPtrNewtype a => a -> Ptr b-unsafeManagedPtrCastPtr x = let p = coerce x :: ForeignPtr ()-                            in castPtr (unsafeForeignPtrToPtr p)---- | Ensure that the 'Ptr' in the given managed pointer is still alive--- (i.e. it has not been garbage collected by the runtime) at the--- point that this is called.-touchManagedPtr :: forall a. ForeignPtrNewtype a => a -> IO ()-touchManagedPtr x = let p = coerce x :: ForeignPtr ()-                     in touchForeignPtr p---- Safe casting machinery-foreign import ccall unsafe "check_object_type"-    c_check_object_type :: Ptr o -> CGType -> CInt---- | Cast to the given type, checking that the cast is valid. If it is--- not, we return `Nothing`. Usage:------ > maybeWidget <- castTo Widget label-castTo :: forall o o'. (GObject o, GObject o') =>-          (ForeignPtr o' -> o') -> o -> IO (Maybe o')-castTo constructor obj =-    withManagedPtr obj $ \objPtr -> do-      GType t <- gobjectType (undefined :: o')-      if c_check_object_type objPtr t /= 1-        then return Nothing-        else Just <$> newObject constructor objPtr---- | Cast to the given type, assuming that the cast will succeed. This--- function will call `error` if the cast is illegal.-unsafeCastTo :: forall o o'. (HasCallStack, GObject o, GObject o') =>-                (ForeignPtr o' -> o') -> o -> IO o'-unsafeCastTo constructor obj =-  withManagedPtr obj $ \objPtr -> do-    GType t <- gobjectType (undefined :: o')-    if c_check_object_type objPtr t /= 1-      then do-      srcType <- gobjectType obj >>= gtypeName-      destType <- gobjectType (undefined :: o') >>= gtypeName-      error $ "unsafeCastTo :: invalid conversion from " ++ srcType ++ " to "-        ++ destType ++ " requested."-      else newObject constructor objPtr---- Reference counting for constructors-foreign import ccall "&dbg_g_object_unref"-    ptr_to_g_object_unref :: FunPtr (Ptr a -> IO ())--foreign import ccall "g_object_ref" g_object_ref ::-    Ptr a -> IO (Ptr a)---- | Construct a Haskell wrapper for a 'GObject', increasing its--- reference count.-newObject :: (GObject a, GObject b) => (ForeignPtr a -> a) -> Ptr b -> IO a-newObject constructor ptr = do-  void $ g_object_ref ptr-  fPtr <- newManagedPtr ptr_to_g_object_unref $ castPtr ptr-  return $! constructor fPtr--foreign import ccall "g_object_ref_sink" g_object_ref_sink ::-    Ptr a -> IO (Ptr a)---- | Same as 'newObject', but we take ownership of the object. Newly--- created 'GObject's are typically floating, so we use--- <https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-ref-sink g_object_ref_sink>.---- Notice that the--- semantics here are a little bit subtle: some objects (such as--- GtkWindow, see the code about "user_ref_count" in gtkwindow.c in--- the gtk+ distribution) are created /without/ the floating flag,--- since they own a reference to themselves. So, wrapping them is--- really about adding a ref. If we add the ref, when Haskell drops--- the last ref to the 'GObject' it will /g_object_unref/, and the--- window will /g_object_unref/ itself upon destruction, so by the end--- we don't leak memory. If we don't add the ref, there will be two--- /g_object_unrefs/ acting on the object (one from Haskell and one from--- the GtkWindow destroy) when the object is destroyed and the second--- one will give a segfault.------ This is the story for GInitiallyUnowned objects (e.g. anything that--- is a descendant from GtkWidget). For objects that are not initially--- floating (i.e. not descendents of GInitiallyUnowned) we simply take--- control of the reference.-wrapObject :: forall a b. (GObject a, GObject b) =>-              (ForeignPtr a -> a) -> Ptr b -> IO a-wrapObject constructor ptr = do-  when (gobjectIsInitiallyUnowned (undefined :: a)) $-       void $ g_object_ref_sink ptr-  fPtr <- newManagedPtr ptr_to_g_object_unref $ castPtr ptr-  return $! constructor fPtr---- | Increase the reference count of the given 'GObject'.-refObject :: (GObject a, GObject b) => a -> IO (Ptr b)-refObject obj = castPtr <$> withManagedPtr obj g_object_ref--foreign import ccall "g_object_unref" g_object_unref ::-    Ptr a -> IO ()---- | Decrease the reference count of the given 'GObject'. The memory--- associated with the object may be released if the reference count--- reaches 0.-unrefObject :: GObject a => a -> IO ()-unrefObject obj = withManagedPtr obj g_object_unref--foreign import ccall "boxed_free_helper" boxed_free_helper ::-    CGType -> Ptr a -> IO ()--foreign import ccall "g_boxed_copy" g_boxed_copy ::-    CGType -> Ptr a -> IO (Ptr a)---- | Construct a Haskell wrapper for the given boxed object. We make a--- copy of the object.-newBoxed :: forall a. BoxedObject a => (ForeignPtr a -> a) -> Ptr a -> IO a-newBoxed constructor ptr = do-  GType gtype <- boxedType (undefined :: a)-  ptr' <- g_boxed_copy gtype ptr-  fPtr <- FC.newForeignPtr ptr' (boxed_free_helper gtype ptr')-  return $! constructor fPtr---- | Like 'newBoxed', but we do not make a copy (we "steal" the passed--- object, so now it is managed by the Haskell runtime).-wrapBoxed :: forall a. BoxedObject a => (ForeignPtr a -> a) -> Ptr a -> IO a-wrapBoxed constructor ptr = do-  GType gtype <- boxedType (undefined :: a)-  fPtr <- FC.newForeignPtr ptr (boxed_free_helper gtype ptr)-  return $! constructor fPtr---- | Make a copy of the given boxed object.-copyBoxed :: forall a. BoxedObject a => a -> IO (Ptr a)-copyBoxed boxed = withManagedPtr boxed copyBoxedPtr---- | Like 'copyBoxed', but acting directly on a pointer, instead of a--- managed pointer.-copyBoxedPtr :: forall a. BoxedObject a => Ptr a -> IO (Ptr a)-copyBoxedPtr ptr = do-  GType gtype <- boxedType (undefined :: a)-  g_boxed_copy gtype ptr--foreign import ccall "g_boxed_free" g_boxed_free ::-    CGType -> Ptr a -> IO ()---- | Free the memory associated with a boxed object-freeBoxed :: forall a. BoxedObject a => a -> IO ()-freeBoxed boxed = do-  GType gtype <- boxedType (undefined :: a)-  let ptr = unsafeManagedPtrGetPtr boxed-  g_boxed_free gtype ptr-  touchManagedPtr boxed---- | Wrap a pointer, taking ownership of it.-wrapPtr :: WrappedPtr a => (ForeignPtr a -> a) -> Ptr a -> IO a-wrapPtr constructor ptr = do-  fPtr <- case wrappedPtrFree of-            Nothing -> newForeignPtr_ ptr-            Just finalizer -> newManagedPtr finalizer ptr-  return $! constructor fPtr---- | Wrap a pointer, making a copy of the data.-newPtr :: WrappedPtr a => (ForeignPtr a -> a) -> Ptr a -> IO a-newPtr constructor ptr = do-  ptr' <- wrappedPtrCopy ptr-  fPtr <- case wrappedPtrFree of-            Nothing -> newForeignPtr_ ptr-            Just finalizer -> newManagedPtr finalizer ptr'-  return $! constructor fPtr---- | Make a copy of a wrapped pointer using @memcpy@ into a freshly--- allocated memory region of the given size.-copyPtr :: WrappedPtr a => Int -> Ptr a -> IO (Ptr a)-copyPtr size ptr = do-  ptr' <- wrappedPtrCalloc-  memcpy ptr' ptr size-  return ptr'
− src/Data/GI/Base/Overloading.hs
@@ -1,263 +0,0 @@-{-# LANGUAGE TypeOperators, KindSignatures, DataKinds, PolyKinds,-             TypeFamilies, UndecidableInstances, EmptyDataDecls,-             MultiParamTypeClasses, FlexibleInstances, ConstraintKinds #-}---- | Helpers for dealing with `GObject`s.--module Data.GI.Base.Overloading-    ( -- * Type level inheritance-      ParentTypes-    , IsDescendantOf-#if MIN_VERSION_base(4,9,0)-    , UnknownAncestorError-#endif--    -- * Looking up attributes in parent types-    , AttributeList-    , HasAttributeList-    , ResolveAttribute-    , HasAttribute-    , HasAttr--    -- * Looking up signals in parent types-    , SignalList-    , ResolveSignal-    , HasSignal--    -- * Looking up methods in parent types-    , MethodInfo(..)-    , MethodProxy(..)-    , MethodResolutionFailed--    -- * Overloaded labels-    , IsLabelProxy(..)--#if MIN_VERSION_base(4,9,0)-    , module GHC.OverloadedLabels       -- Reexported for convenience-#endif-    ) where--import GHC.Exts (Constraint)-import GHC.TypeLits-import Data.Proxy (Proxy)--#if MIN_VERSION_base(4,9,0)-import GHC.OverloadedLabels (IsLabel(..))-#endif---- | Support for overloaded labels in ghc < 8.0. This is like the--- `IsLabel` class introduced in ghc 8.0 (for use with the--- OverloadedLabels extension) with the difference that the `Proxy`--- argument is lifted. (Using the unlifted Proxy# type in user code is--- a bit of a pain, hence the choice.)-class IsLabelProxy (x :: Symbol) a where-  fromLabelProxy :: Proxy x -> a---- | Join two lists.-type family JoinLists (as :: [a]) (bs :: [a]) :: [a] where-    JoinLists '[] bs = bs-    JoinLists (a ': as) bs = a ': JoinLists as bs---- | Look in the given list of (symbol, tag) tuples for the tag--- corresponding to the given symbol. If not found raise the given--- type error.-type family FindElement (m :: Symbol) (ms :: [(Symbol, *)])-#if !MIN_VERSION_base(4,9,0)-    (typeError :: *)-#else-    (typeError :: ErrorMessage)-#endif-    :: * where-    FindElement m '[] typeError =-#if !MIN_VERSION_base(4,9,0)-        typeError-#else-        TypeError typeError-#endif-    FindElement m ('(m, o) ': ms) typeError = o-    FindElement m ('(m', o) ': ms) typeError = FindElement m ms typeError---- | Result of a ancestor check. Basically a Bool type with a bit of--- extra info in order to improve typechecker error messages.-data AncestorCheck t a = HasAncestor a t-#if !MIN_VERSION_base(4,9,0)-                       | DoesNotHaveRequiredAncestor Symbol t Symbol a-#endif--#if MIN_VERSION_base(4,9,0)--- | Type error to be generated when an ancestor check fails.-type family UnknownAncestorError (a :: *) (t :: *) where-    UnknownAncestorError a t =-        TypeError ('Text "Required ancestor ‘" ':<>: 'ShowType a-                   ':<>: 'Text "’ not found for type ‘"-                   ':<>: 'ShowType t ':<>: 'Text "’.")-#endif---- | Check whether a type appears in a list. We specialize the--- names/types a bit so the error messages are more informative.-type family CheckForAncestorType t (a :: *) (as :: [*]) :: AncestorCheck * * where-    CheckForAncestorType t a '[] =-#if !MIN_VERSION_base(4,9,0)-        'DoesNotHaveRequiredAncestor "Error: Required ancestor" a "not found for type" t-#else-        UnknownAncestorError a t-#endif-    CheckForAncestorType t a (a ': as) = 'HasAncestor a t-    CheckForAncestorType t a (b ': as) = CheckForAncestorType t a as---- | Check that a type is in the list of `GObjectParents` of another--- `GObject`-derived type.-type family IsDescendantOf (parent :: *) (descendant :: *) :: Constraint where-    -- Every object is defined to be a descendant of itself.-    IsDescendantOf d d = () ~ ()-    IsDescendantOf p d = CheckForAncestorType d p (ParentTypes d) ~ 'HasAncestor p d---- | The direct parents of this object: its direct parent type, if any,--- and the interfaces it implements. The interfaces inherited from--- parent types can be omitted.-type family ParentTypes a :: [*]---- | The list of attributes defined for a given type. Each element of--- the list is a tuple, with the first element of the tuple the name--- of the attribute, and the second the type encoding the information--- of the attribute. This type will be an instance of `AttrInfo`.-type family AttributeList a :: [(Symbol, *)]---- | A constraint on a type, to be fulfilled whenever it has a type--- instance for `AttributeList`. This is here for nicer error--- reporting.-class HasAttributeList a--#if MIN_VERSION_base(4,9,0)--- Default instance, which will give rise to an error for types--- without an associated `AttributeList`.-instance {-# OVERLAPPABLE #-}-    TypeError ('Text "Type ‘" ':<>: 'ShowType a ':<>:-               'Text "’ does not have any known attributes.")-    => HasAttributeList a-#endif--#if !MIN_VERSION_base(4,9,0)--- | Datatype returned when the attribute is not found, hopefully making--- the resulting error messages somewhat clearer.-data UnknownAttribute (msg1 :: Symbol) (s :: Symbol) (msg2 :: Symbol) (o :: *)-#endif---- | Return the type encoding the attribute information for a given--- type and attribute.-type family ResolveAttribute (s :: Symbol) (o :: *) :: * where-    ResolveAttribute s o = FindElement s (AttributeList o)-#if !MIN_VERSION_base(4,9,0)-                           (UnknownAttribute "Error: could not find attribute" s "for object" o)-#else-                           ('Text "Unknown attribute ‘" ':<>:-                            'Text s ':<>: 'Text "’ for object ‘" ':<>:-                            'ShowType o ':<>: 'Text "’.")-#endif---- | Whether a given type is in the given list. If found, return--- @success@, otherwise return @failure@.-type family IsElem (e :: Symbol) (es :: [(Symbol, *)]) (success :: k)-#if !MIN_VERSION_base(4,9,0)-    (failure :: k)-#else-    (failure :: ErrorMessage)-#endif-        :: k where-    IsElem e '[] success failure =-#if !MIN_VERSION_base(4,9,0)-        failure-#else-        TypeError failure-#endif-    IsElem e ( '(e, t) ': es) success failure = success-    IsElem e ( '(other, t) ': es) s f = IsElem e es s f---- | Isomorphic to Bool, but having some extra debug information.-data AttributeCheck a t = HasAttribute-#if !MIN_VERSION_base(4,9,0)-                        | DoesNotHaveAttribute Symbol a Symbol t-#endif---- | A constraint imposing that the given object has the given attribute.-type family HasAttribute (attr :: Symbol) (o :: *) where-    HasAttribute attr o = IsElem attr (AttributeList o)-                          'HasAttribute-#if !MIN_VERSION_base(4,9,0)-                          ('DoesNotHaveAttribute "Error: attribute" attr "not found for type" o)-#else-                          ('Text "Attribute ‘" ':<>: 'Text attr ':<>:-                           'Text "’ not found for type ‘" ':<>:-                           'ShowType o ':<>: 'Text "’.")-#endif-                          ~ 'HasAttribute---- | A constraint that enforces that the given type has a given attribute.-class HasAttr (attr :: Symbol) (o :: *)-instance HasAttribute attr o => HasAttr attr o---- | The list of signals defined for a given type. Each element of--- the list is a tuple, with the first element of the tuple the name--- of the signal, and the second the type encoding the information of--- the signal. This type will be an instance of `SignalInfo`.-type family SignalList a :: [(Symbol, *)]--#if !MIN_VERSION_base(4,9,0)--- | Datatype returned when the signal is not found, hopefully making--- the resulting error messages somewhat clearer.-data UnknownSignal (msg1 :: Symbol) (s :: Symbol) (msg2 :: Symbol) (o :: *)-#endif---- | Return the type encoding the signal information for a given--- type and signal.-type family ResolveSignal (s :: Symbol) (o :: *) :: * where-    ResolveSignal s o = FindElement s (SignalList o)-#if !MIN_VERSION_base(4,9,0)-                        (UnknownSignal "Error: could not find signal" s "for object" o)-#else-                        ('Text "Unknown signal ‘" ':<>:-                         'Text s ':<>: 'Text "’ for object ‘" ':<>:-                         'ShowType o ':<>: 'Text "’.")-#endif---- | Isomorphic to Bool, but having some extra debug information.-data SignalCheck s t = HasSignal-#if !MIN_VERSION_base(4,9,0)-                     | DoesNotHaveSignal Symbol s Symbol t-#endif---- | A constraint enforcing that the signal exists for the given--- object, or one of its ancestors.-type family HasSignal (s :: Symbol) (o :: *) where-    HasSignal s o = IsElem s (SignalList o)-                    'HasSignal-#if !MIN_VERSION_base(4,9,0)-                    ('DoesNotHaveSignal "Error: signal" s "not found for type" o)-#else-                    ('Text "Signal ‘" ':<>: 'Text s ':<>:-                     'Text "’ not found for type ‘" ':<>:-                     'ShowType o ':<>: 'Text "’.")-#endif-                    ~ 'HasSignal---- | Class for types containing the information about an overloaded--- method of type `o -> s`.-class MethodInfo i o s where-    overloadedMethod :: MethodProxy i -> o -> s---- | Proxy for passing a type to `overloadedMethod`. We do not use--- `Data.Proxy.Proxy` directly since it clashes with types defined in--- the autogenerated bindings.-data MethodProxy a = MethodProxy--#if !MIN_VERSION_base(4,9,0)--- | Datatype returned when the method is not found, hopefully making--- the resulting error messages somewhat clearer.-data MethodResolutionFailed (label :: Symbol) (o :: *)-#else-type family MethodResolutionFailed (method :: Symbol) (o :: *) where-    MethodResolutionFailed m o =-        TypeError ('Text "Unknown method ‘" ':<>:-                   'Text m ':<>: 'Text "’ for type ‘" ':<>:-                   'ShowType o ':<>: 'Text "’.")-#endif
− src/Data/GI/Base/Properties.hsc
@@ -1,521 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}--module Data.GI.Base.Properties-    ( setObjectPropertyString-    , setObjectPropertyStringArray-    , setObjectPropertyPtr-    , setObjectPropertyInt-    , setObjectPropertyUInt-    , setObjectPropertyLong-    , setObjectPropertyULong-    , setObjectPropertyInt32-    , setObjectPropertyUInt32-    , setObjectPropertyInt64-    , setObjectPropertyUInt64-    , setObjectPropertyFloat-    , setObjectPropertyDouble-    , setObjectPropertyBool-    , setObjectPropertyGType-    , setObjectPropertyObject-    , setObjectPropertyBoxed-    , setObjectPropertyEnum-    , setObjectPropertyFlags-    , setObjectPropertyVariant-    , setObjectPropertyByteArray-    , setObjectPropertyPtrGList-    , setObjectPropertyHash--    , getObjectPropertyString-    , getObjectPropertyStringArray-    , getObjectPropertyPtr-    , getObjectPropertyInt-    , getObjectPropertyUInt-    , getObjectPropertyLong-    , getObjectPropertyULong-    , getObjectPropertyInt32-    , getObjectPropertyUInt32-    , getObjectPropertyInt64-    , getObjectPropertyUInt64-    , getObjectPropertyFloat-    , getObjectPropertyDouble-    , getObjectPropertyBool-    , getObjectPropertyGType-    , getObjectPropertyObject-    , getObjectPropertyBoxed-    , getObjectPropertyEnum-    , getObjectPropertyFlags-    , getObjectPropertyVariant-    , getObjectPropertyByteArray-    , getObjectPropertyPtrGList-    , getObjectPropertyHash--    , constructObjectPropertyString-    , constructObjectPropertyStringArray-    , constructObjectPropertyPtr-    , constructObjectPropertyInt-    , constructObjectPropertyUInt-    , constructObjectPropertyLong-    , constructObjectPropertyULong-    , constructObjectPropertyInt32-    , constructObjectPropertyUInt32-    , constructObjectPropertyInt64-    , constructObjectPropertyUInt64-    , constructObjectPropertyFloat-    , constructObjectPropertyDouble-    , constructObjectPropertyBool-    , constructObjectPropertyGType-    , constructObjectPropertyObject-    , constructObjectPropertyBoxed-    , constructObjectPropertyEnum-    , constructObjectPropertyFlags-    , constructObjectPropertyVariant-    , constructObjectPropertyByteArray-    , constructObjectPropertyPtrGList-    , constructObjectPropertyHash-    ) where--#if !MIN_VERSION_base(4,8,0)-import Control.Applicative ((<$>))-#endif-import Control.Monad ((>=>))--import qualified Data.ByteString.Char8 as B-import Data.Text (Text)-import Data.Proxy (Proxy(..))--import Data.GI.Base.BasicTypes-import Data.GI.Base.BasicConversions-import Data.GI.Base.ManagedPtr-import Data.GI.Base.GValue-import Data.GI.Base.GVariant (newGVariantFromPtr)-import Data.GI.Base.Utils (freeMem, convertIfNonNull)--import Foreign (Ptr, ForeignPtr, Int32, Word32, Int64, Word64, nullPtr)-import Foreign.C (CString, withCString)-import Foreign.C.Types (CInt, CUInt, CLong, CULong)--#include <glib-object.h>--foreign import ccall "g_object_set_property" g_object_set_property ::-    Ptr a -> CString -> Ptr GValue -> IO ()--setObjectProperty :: GObject a => a -> String -> b ->-                     (GValue -> b -> IO ()) -> GType -> IO ()-setObjectProperty obj propName propValue setter (GType gtype) = do-  gvalue <- buildGValue (GType gtype) setter propValue-  withManagedPtr obj $ \objPtr ->-      withCString propName $ \cPropName ->-          withManagedPtr gvalue $ \gvalueptr ->-              g_object_set_property objPtr cPropName gvalueptr--foreign import ccall "g_object_get_property" g_object_get_property ::-    Ptr a -> CString -> Ptr GValue -> IO ()--getObjectProperty :: GObject a => a -> String ->-                     (GValue -> IO b) -> GType -> IO b-getObjectProperty obj propName getter gtype = do-  gvalue <- newGValue gtype-  withManagedPtr obj $ \objPtr ->-      withCString propName $ \cPropName ->-          withManagedPtr gvalue $ \gvalueptr ->-              g_object_get_property objPtr cPropName gvalueptr-  getter gvalue--constructObjectProperty :: String -> b -> (GValue -> b -> IO ()) ->-                           GType -> IO (GValueConstruct o)-constructObjectProperty propName propValue setter gtype = do-  gvalue <- buildGValue gtype setter propValue-  return (GValueConstruct propName gvalue)--setObjectPropertyString :: GObject a =>-                           a -> String -> Maybe Text -> IO ()-setObjectPropertyString obj propName str =-    setObjectProperty obj propName str set_string gtypeString--constructObjectPropertyString :: String -> Maybe Text ->-                                 IO (GValueConstruct o)-constructObjectPropertyString propName str =-    constructObjectProperty propName str set_string gtypeString--getObjectPropertyString :: GObject a =>-                           a -> String -> IO (Maybe Text)-getObjectPropertyString obj propName =-    getObjectProperty obj propName get_string gtypeString--setObjectPropertyPtr :: GObject a =>-                        a -> String -> Ptr b -> IO ()-setObjectPropertyPtr obj propName ptr =-    setObjectProperty obj propName ptr set_pointer gtypePointer--constructObjectPropertyPtr :: String -> Ptr b ->-                              IO (GValueConstruct o)-constructObjectPropertyPtr propName ptr =-    constructObjectProperty propName ptr set_pointer gtypePointer--getObjectPropertyPtr :: GObject a =>-                        a -> String -> IO (Ptr b)-getObjectPropertyPtr obj propName =-    getObjectProperty obj propName get_pointer gtypePointer--setObjectPropertyInt :: GObject a =>-                         a -> String -> CInt -> IO ()-setObjectPropertyInt obj propName int =-    setObjectProperty obj propName int set_int gtypeInt--constructObjectPropertyInt :: String -> CInt ->-                              IO (GValueConstruct o)-constructObjectPropertyInt propName int =-    constructObjectProperty propName int set_int gtypeInt--getObjectPropertyInt :: GObject a => a -> String -> IO CInt-getObjectPropertyInt obj propName =-    getObjectProperty obj propName get_int gtypeInt--setObjectPropertyUInt :: GObject a =>-                          a -> String -> CUInt -> IO ()-setObjectPropertyUInt obj propName uint =-    setObjectProperty obj propName uint set_uint gtypeUInt--constructObjectPropertyUInt :: String -> CUInt ->-                                IO (GValueConstruct o)-constructObjectPropertyUInt propName uint =-    constructObjectProperty propName uint set_uint gtypeUInt--getObjectPropertyUInt :: GObject a => a -> String -> IO CUInt-getObjectPropertyUInt obj propName =-    getObjectProperty obj propName get_uint gtypeUInt--setObjectPropertyLong :: GObject a =>-                         a -> String -> CLong -> IO ()-setObjectPropertyLong obj propName int =-    setObjectProperty obj propName int set_long gtypeLong--constructObjectPropertyLong :: String -> CLong ->-                               IO (GValueConstruct o)-constructObjectPropertyLong propName int =-    constructObjectProperty propName int set_long gtypeLong--getObjectPropertyLong :: GObject a => a -> String -> IO CLong-getObjectPropertyLong obj propName =-    getObjectProperty obj propName get_long gtypeLong--setObjectPropertyULong :: GObject a =>-                          a -> String -> CULong -> IO ()-setObjectPropertyULong obj propName uint =-    setObjectProperty obj propName uint set_ulong gtypeULong--constructObjectPropertyULong :: String -> CULong ->-                                IO (GValueConstruct o)-constructObjectPropertyULong propName uint =-    constructObjectProperty propName uint set_ulong gtypeULong--getObjectPropertyULong :: GObject a => a -> String -> IO CULong-getObjectPropertyULong obj propName =-    getObjectProperty obj propName get_ulong gtypeULong--setObjectPropertyInt32 :: GObject a =>-                          a -> String -> Int32 -> IO ()-setObjectPropertyInt32 obj propName int32 =-    setObjectProperty obj propName int32 set_int32 gtypeInt--constructObjectPropertyInt32 :: String -> Int32 ->-                                IO (GValueConstruct o)-constructObjectPropertyInt32 propName int32 =-    constructObjectProperty propName int32 set_int32 gtypeInt--getObjectPropertyInt32 :: GObject a => a -> String -> IO Int32-getObjectPropertyInt32 obj propName =-    getObjectProperty obj propName get_int32 gtypeInt--setObjectPropertyUInt32 :: GObject a =>-                          a -> String -> Word32 -> IO ()-setObjectPropertyUInt32 obj propName uint32 =-    setObjectProperty obj propName uint32 set_uint32 gtypeUInt--constructObjectPropertyUInt32 :: String -> Word32 ->-                                 IO (GValueConstruct o)-constructObjectPropertyUInt32 propName uint32 =-    constructObjectProperty propName uint32 set_uint32 gtypeUInt--getObjectPropertyUInt32 :: GObject a => a -> String -> IO Word32-getObjectPropertyUInt32 obj propName =-    getObjectProperty obj propName get_uint32 gtypeUInt--setObjectPropertyInt64 :: GObject a =>-                          a -> String -> Int64 -> IO ()-setObjectPropertyInt64 obj propName int64 =-    setObjectProperty obj propName int64 set_int64 gtypeInt64--constructObjectPropertyInt64 :: String -> Int64 ->-                                IO (GValueConstruct o)-constructObjectPropertyInt64 propName int64 =-    constructObjectProperty propName int64 set_int64 gtypeInt64--getObjectPropertyInt64 :: GObject a => a -> String -> IO Int64-getObjectPropertyInt64 obj propName =-    getObjectProperty obj propName get_int64 gtypeInt64--setObjectPropertyUInt64 :: GObject a =>-                          a -> String -> Word64 -> IO ()-setObjectPropertyUInt64 obj propName uint64 =-    setObjectProperty obj propName uint64 set_uint64 gtypeUInt64--constructObjectPropertyUInt64 :: String -> Word64 ->-                                 IO (GValueConstruct o)-constructObjectPropertyUInt64 propName uint64 =-    constructObjectProperty propName uint64 set_uint64 gtypeUInt64--getObjectPropertyUInt64 :: GObject a => a -> String -> IO Word64-getObjectPropertyUInt64 obj propName =-    getObjectProperty obj propName get_uint64 gtypeUInt64--setObjectPropertyFloat :: GObject a =>-                           a -> String -> Float -> IO ()-setObjectPropertyFloat obj propName float =-    setObjectProperty obj propName float set_float gtypeFloat--constructObjectPropertyFloat :: String -> Float ->-                                 IO (GValueConstruct o)-constructObjectPropertyFloat propName float =-    constructObjectProperty propName float set_float gtypeFloat--getObjectPropertyFloat :: GObject a =>-                           a -> String -> IO Float-getObjectPropertyFloat obj propName =-    getObjectProperty obj propName get_float gtypeFloat--setObjectPropertyDouble :: GObject a =>-                            a -> String -> Double -> IO ()-setObjectPropertyDouble obj propName double =-    setObjectProperty obj propName double set_double gtypeDouble--constructObjectPropertyDouble :: String -> Double ->-                                  IO (GValueConstruct o)-constructObjectPropertyDouble propName double =-    constructObjectProperty propName double set_double gtypeDouble--getObjectPropertyDouble :: GObject a =>-                            a -> String -> IO Double-getObjectPropertyDouble obj propName =-    getObjectProperty obj propName get_double gtypeDouble--setObjectPropertyBool :: GObject a =>-                         a -> String -> Bool -> IO ()-setObjectPropertyBool obj propName bool =-    setObjectProperty obj propName bool set_boolean gtypeBoolean--constructObjectPropertyBool :: String -> Bool -> IO (GValueConstruct o)-constructObjectPropertyBool propName bool =-    constructObjectProperty propName bool set_boolean gtypeBoolean--getObjectPropertyBool :: GObject a => a -> String -> IO Bool-getObjectPropertyBool obj propName =-    getObjectProperty obj propName get_boolean gtypeBoolean--setObjectPropertyGType :: GObject a =>-                         a -> String -> GType -> IO ()-setObjectPropertyGType obj propName gtype =-    setObjectProperty obj propName gtype set_gtype gtypeGType--constructObjectPropertyGType :: String -> GType -> IO (GValueConstruct o)-constructObjectPropertyGType propName bool =-    constructObjectProperty propName bool set_gtype gtypeGType--getObjectPropertyGType :: GObject a => a -> String -> IO GType-getObjectPropertyGType obj propName =-    getObjectProperty obj propName get_gtype gtypeGType--setObjectPropertyObject :: forall a b. (GObject a, GObject b) =>-                           a -> String -> Maybe b -> IO ()-setObjectPropertyObject obj propName maybeObject = do-  gtype <- gobjectType (undefined :: b)-  maybeWithManagedPtr maybeObject $ \objectPtr ->-      setObjectProperty obj propName objectPtr set_object gtype--constructObjectPropertyObject :: forall a o. GObject a =>-                                 String -> Maybe a -> IO (GValueConstruct o)-constructObjectPropertyObject propName maybeObject = do-  gtype <- gobjectType (undefined :: a)-  maybeWithManagedPtr maybeObject $ \objectPtr ->-      constructObjectProperty propName objectPtr set_object gtype--getObjectPropertyObject :: forall a b. (GObject a, GObject b) =>-                           a -> String -> (ForeignPtr b -> b) -> IO (Maybe b)-getObjectPropertyObject obj propName constructor = do-  gtype <- gobjectType (undefined :: b)-  getObjectProperty obj propName-                        (\val -> (get_object val :: IO (Ptr b))-                            >>= flip convertIfNonNull (newObject constructor))-                      gtype--setObjectPropertyBoxed :: forall a b. (GObject a, BoxedObject b) =>-                          a -> String -> Maybe b -> IO ()-setObjectPropertyBoxed obj propName maybeBoxed = do-  gtype <- boxedType (undefined :: b)-  maybeWithManagedPtr maybeBoxed $ \boxedPtr ->-        setObjectProperty obj propName boxedPtr set_boxed gtype--constructObjectPropertyBoxed :: forall a o. (BoxedObject a) =>-                                String -> Maybe a -> IO (GValueConstruct o)-constructObjectPropertyBoxed propName maybeBoxed = do-  gtype <- boxedType (undefined :: a)-  maybeWithManagedPtr maybeBoxed $ \boxedPtr ->-      constructObjectProperty propName boxedPtr set_boxed gtype--getObjectPropertyBoxed :: forall a b. (GObject a, BoxedObject b) =>-                          a -> String -> (ForeignPtr b -> b) -> IO (Maybe b)-getObjectPropertyBoxed obj propName constructor = do-  gtype <- boxedType (undefined :: b)-  getObjectProperty obj propName (get_boxed >=>-                                  flip convertIfNonNull (newBoxed constructor))-                    gtype--setObjectPropertyStringArray :: GObject a =>-                                a -> String -> Maybe [Text] -> IO ()-setObjectPropertyStringArray obj propName Nothing =-  setObjectProperty obj propName nullPtr set_boxed gtypeStrv-setObjectPropertyStringArray obj propName (Just strv) = do-  cStrv <- packZeroTerminatedUTF8CArray strv-  setObjectProperty obj propName cStrv set_boxed gtypeStrv-  mapZeroTerminatedCArray freeMem cStrv-  freeMem cStrv--constructObjectPropertyStringArray :: String -> Maybe [Text] ->-                                      IO (GValueConstruct o)-constructObjectPropertyStringArray propName Nothing =-  constructObjectProperty propName nullPtr set_boxed gtypeStrv-constructObjectPropertyStringArray propName (Just strv) = do-  cStrv <- packZeroTerminatedUTF8CArray strv-  result <- constructObjectProperty propName cStrv set_boxed gtypeStrv-  mapZeroTerminatedCArray freeMem cStrv-  freeMem cStrv-  return result--getObjectPropertyStringArray :: GObject a => a -> String -> IO (Maybe [Text])-getObjectPropertyStringArray obj propName =-    getObjectProperty obj propName-                      (get_boxed >=>-                       flip convertIfNonNull unpackZeroTerminatedUTF8CArray)-                      gtypeStrv--setObjectPropertyEnum :: (GObject a, Enum b, BoxedEnum b) =>-                         a -> String -> b -> IO ()-setObjectPropertyEnum obj propName enum = do-  gtype <- boxedEnumType enum-  let cEnum = (fromIntegral . fromEnum) enum-  setObjectProperty obj propName cEnum set_enum gtype--constructObjectPropertyEnum :: (Enum a, BoxedEnum a) =>-                               String -> a -> IO (GValueConstruct o)-constructObjectPropertyEnum propName enum = do-  gtype <- boxedEnumType enum-  let cEnum = (fromIntegral . fromEnum) enum-  constructObjectProperty propName cEnum set_enum gtype--getObjectPropertyEnum :: forall a b. (GObject a,-                                      Enum b, BoxedEnum b) =>-                         a -> String -> IO b-getObjectPropertyEnum obj propName = do-  gtype <- boxedEnumType (undefined :: b)-  getObjectProperty obj propName-                    (\val -> toEnum . fromIntegral <$> get_enum val)-                    gtype--setObjectPropertyFlags :: forall a b. (IsGFlag b, BoxedFlags b, GObject a) =>-                          a -> String -> [b] -> IO ()-setObjectPropertyFlags obj propName flags = do-  let cFlags = gflagsToWord flags-  gtype <- boxedFlagsType (Proxy :: Proxy b)-  setObjectProperty obj propName cFlags set_flags gtype--constructObjectPropertyFlags :: forall a o. (IsGFlag a, BoxedFlags a)-                                => String -> [a] -> IO (GValueConstruct o)-constructObjectPropertyFlags propName flags = do-  let cFlags = gflagsToWord flags-  gtype <- boxedFlagsType (Proxy :: Proxy a)-  constructObjectProperty propName cFlags set_flags gtype--getObjectPropertyFlags :: forall a b. (GObject a, IsGFlag b, BoxedFlags b) =>-                          a -> String -> IO [b]-getObjectPropertyFlags obj propName = do-  gtype <- boxedFlagsType (Proxy :: Proxy b)-  getObjectProperty obj propName-                        (\val -> wordToGFlags <$> get_flags val)-                        gtype--setObjectPropertyVariant :: GObject a =>-                            a -> String -> Maybe GVariant -> IO ()-setObjectPropertyVariant obj propName maybeVariant =-    maybeWithManagedPtr maybeVariant $ \variantPtr ->-        setObjectProperty obj propName variantPtr set_variant gtypeVariant--constructObjectPropertyVariant :: String -> Maybe GVariant-                               -> IO (GValueConstruct o)-constructObjectPropertyVariant propName maybeVariant =-    maybeWithManagedPtr maybeVariant $ \objPtr ->-        constructObjectProperty propName objPtr set_variant gtypeVariant--getObjectPropertyVariant :: GObject a => a -> String ->-                            IO (Maybe GVariant)-getObjectPropertyVariant obj propName =-    getObjectProperty obj propName (get_variant >=>-                                    flip convertIfNonNull newGVariantFromPtr)-                      gtypeVariant--setObjectPropertyByteArray :: GObject a =>-                              a -> String -> Maybe B.ByteString -> IO ()-setObjectPropertyByteArray obj propName Nothing =-    setObjectProperty obj propName nullPtr set_boxed gtypeByteArray-setObjectPropertyByteArray obj propName (Just bytes) = do-  packed <- packGByteArray bytes-  setObjectProperty obj propName packed set_boxed gtypeByteArray-  unrefGByteArray packed--constructObjectPropertyByteArray :: String -> Maybe B.ByteString ->-                                    IO (GValueConstruct o)-constructObjectPropertyByteArray propName Nothing =-    constructObjectProperty propName nullPtr set_boxed gtypeByteArray-constructObjectPropertyByteArray propName (Just bytes) = do-  packed <- packGByteArray bytes-  result <- constructObjectProperty propName packed set_boxed gtypeByteArray-  unrefGByteArray packed-  return result--getObjectPropertyByteArray :: GObject a =>-                              a -> String -> IO (Maybe B.ByteString)-getObjectPropertyByteArray obj propName =-    getObjectProperty obj propName (get_boxed >=>-                                    flip convertIfNonNull unpackGByteArray)-                      gtypeByteArray--setObjectPropertyPtrGList :: GObject a =>-                              a -> String -> [Ptr b] -> IO ()-setObjectPropertyPtrGList obj propName ptrs = do-  packed <- packGList ptrs-  setObjectProperty obj propName packed set_boxed gtypePointer-  g_list_free packed--constructObjectPropertyPtrGList :: String -> [Ptr a] ->-                                    IO (GValueConstruct o)-constructObjectPropertyPtrGList propName ptrs = do-  packed <- packGList ptrs-  result <- constructObjectProperty propName packed set_boxed gtypePointer-  g_list_free packed-  return result--getObjectPropertyPtrGList :: GObject a =>-                              a -> String -> IO [Ptr b]-getObjectPropertyPtrGList obj propName =-    getObjectProperty obj propName (get_pointer >=> unpackGList) gtypePointer--setObjectPropertyHash :: GObject a => a -> String -> b -> IO ()-setObjectPropertyHash =-    error $ "Setting GHashTable properties not supported yet."--constructObjectPropertyHash :: String -> b -> IO (GValueConstruct o)-constructObjectPropertyHash =-    error $ "Constructing GHashTable properties not supported yet."--getObjectPropertyHash :: GObject a => a -> String -> IO b-getObjectPropertyHash =-    error $ "Getting GHashTable properties not supported yet."
− src/Data/GI/Base/ShortPrelude.hs
@@ -1,93 +0,0 @@--- | The Haskell Prelude exports a number of symbols that can easily--- collide with functions appearing in bindings. The generated code--- requires just a small subset of the functions in the Prelude,--- together with some of the functionality in Data.GI.Base, we--- reexport this explicitly here.-module Data.GI.Base.ShortPrelude-    ( module Data.Char-    , module Data.Int-    , module Data.Word-    , module Data.ByteString.Char8-    , module Foreign.C-    , module Foreign.Ptr-    , module Foreign.ForeignPtr-    , module Foreign.ForeignPtr.Unsafe-    , module Foreign.Storable-    , module Control.Applicative-    , module Control.Exception-    , module Control.Monad.IO.Class--    , module Data.GI.Base.Attributes-    , module Data.GI.Base.BasicTypes-    , module Data.GI.Base.BasicConversions-    , module Data.GI.Base.Closure-    , module Data.GI.Base.Constructible-    , module Data.GI.Base.GError-    , module Data.GI.Base.GHashTable-    , module Data.GI.Base.GParamSpec-    , module Data.GI.Base.GObject-    , module Data.GI.Base.GVariant-    , module Data.GI.Base.GValue-    , module Data.GI.Base.ManagedPtr-    , module Data.GI.Base.Properties-    , module Data.GI.Base.Signals-    , module Data.GI.Base.Utils--    , module GHC.TypeLits--    , Enum(fromEnum, toEnum)-    , Show(..)-    , Eq(..)-    , IO-    , Monad(..)-    , Maybe(..)-    , (.)-    , ($)-    , (++)-    , (=<<)-    , Bool(..)-    , Float-    , Double-    , undefined-    , error-    , map-    , length-    , mapM-    , mapM_-    , when-    , fromIntegral-    , realToFrac-    ) where--import Control.Monad (when)-import Data.Char (Char, ord, chr)-import Data.Int (Int, Int8, Int16, Int32, Int64)-import Data.Word (Word8, Word16, Word32, Word64)-import Data.ByteString.Char8 (ByteString)-import Foreign.C (CInt(..), CUInt(..), CFloat(..), CDouble(..), CString, CIntPtr(..), CUIntPtr(..), CLong(..), CULong(..))-import Foreign.Ptr (Ptr, plusPtr, FunPtr, nullPtr,-                    castFunPtrToPtr, castPtrToFunPtr)-import Foreign.ForeignPtr (ForeignPtr)-import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)-import Foreign.Storable (peek, poke, sizeOf)-import Control.Applicative ((<$>))-import Control.Exception (onException)-import Control.Monad.IO.Class (MonadIO, liftIO)--import Data.GI.Base.Attributes hiding (get, set)-import Data.GI.Base.BasicTypes-import Data.GI.Base.BasicConversions-import Data.GI.Base.Closure-import Data.GI.Base.Constructible-import Data.GI.Base.GError-import Data.GI.Base.GHashTable-import Data.GI.Base.GObject-import Data.GI.Base.GParamSpec-import Data.GI.Base.GVariant-import Data.GI.Base.GValue-import Data.GI.Base.ManagedPtr-import Data.GI.Base.Properties-import Data.GI.Base.Signals (SignalConnectMode(..), connectSignalFunPtr, SignalHandlerId, SignalInfo(..), GObjectNotifySignalInfo)-import Data.GI.Base.Utils--import GHC.TypeLits (Symbol)
− src/Data/GI/Base/Signals.hsc
@@ -1,170 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE EmptyDataDecls #-}-{-# LANGUAGE UndecidableInstances #-}---- | Routines for connecting `GObject`s to signals.-module Data.GI.Base.Signals-    ( on-    , after-    , SignalProxy(..)-    , SignalConnectMode(..)-    , connectSignalFunPtr-    , SignalHandlerId-    , SignalInfo(..)-    , GObjectNotifySignalInfo-    ) where--import Control.Monad.IO.Class (MonadIO, liftIO)-import Data.Proxy (Proxy(..))--import Foreign-import Foreign.C--import GHC.TypeLits--import Data.GI.Base.Attributes (AttrLabelProxy, AttrInfo(AttrLabel))-import Data.GI.Base.BasicTypes-import Data.GI.Base.GParamSpec (newGParamSpecFromPtr)-import Data.GI.Base.ManagedPtr (withManagedPtr)-import Data.GI.Base.Overloading (ResolveSignal,-                                 IsLabelProxy(..), ResolveAttribute)-import Data.GI.Base.Utils (safeFreeFunPtrPtr)--#if MIN_VERSION_base(4,9,0)-import GHC.OverloadedLabels (IsLabel(..))-#else-import Data.GI.Base.Overloading (HasSignal)-#endif---- | Type of a `GObject` signal handler id.-type SignalHandlerId = CULong---- | A class that provides a constraint satisfied by every type.-class NoConstraint a-instance NoConstraint a---- | Support for overloaded signal connectors.-data SignalProxy (object :: *) (info :: *) where-    SignalProxy :: SignalProxy o info-    PropertyNotify :: (info ~ ResolveAttribute propName o,-                       AttrInfo info,-                       pl ~ AttrLabel info) =>-                      AttrLabelProxy propName ->-                      SignalProxy o (GObjectNotifySignalInfo pl)---- | Support for overloaded labels.-instance-#if !MIN_VERSION_base(4,9,0)-    -- This gives better error reporting in ghc < 8.0.-       (HasSignal slot object, info ~ ResolveSignal slot object)-#else-       info ~ ResolveSignal slot object-#endif-    => IsLabelProxy slot (SignalProxy object info) where-    fromLabelProxy _ = SignalProxy--#if MIN_VERSION_base(4,9,0)-instance info ~ ResolveSignal slot object =>-    IsLabel slot (SignalProxy object info) where-    fromLabel _ = SignalProxy-#endif---- | Information about an overloaded signal.-class SignalInfo (info :: *) where-    type HaskellCallbackType info-    -- | Connect a Haskell function to a signal of the given `GObject`,-    -- specifying whether the handler will be called before or after-    -- the default handler.-    connectSignal :: GObject o =>-                     SignalProxy o info ->-                     o ->-                     HaskellCallbackType info ->-                     SignalConnectMode ->-                     IO SignalHandlerId---- | Whether to connect a handler to a signal with `connectSignal` so--- that it runs before/after the default handler for the given signal.-data SignalConnectMode = SignalConnectBefore  -- ^ Run before the default handler.-        | SignalConnectAfter -- ^ Run after the default handler.---- | Same as `connectSignal`, specifying from the beginning that the--- handler is to be run before the default handler.------ > on = connectSignal SignalConnectBefore-on :: forall object info m.-      (GObject object, MonadIO m, SignalInfo info) =>-      object -> SignalProxy object info-             -> HaskellCallbackType info -> m SignalHandlerId-on o p c = liftIO $ connectSignal p o c SignalConnectBefore---- | Connect a signal to a handler, running the handler after the default one.------ > after = connectSignal SignalConnectAfter-after :: forall object info m.-      (GObject object, MonadIO m, SignalInfo info) =>-      object -> SignalProxy object info-             -> HaskellCallbackType info -> m SignalHandlerId-after o p c = liftIO $ connectSignal p o c SignalConnectAfter---- Connecting GObjects to signals-foreign import ccall "g_signal_connect_data" g_signal_connect_data ::-    Ptr a ->                            -- instance-    CString ->                          -- detailed_signal-    FunPtr b ->                         -- c_handler-    Ptr () ->                           -- data-    FunPtr c ->                         -- destroy_data-    CUInt ->                            -- connect_flags-    IO SignalHandlerId---- | Connect a signal to a handler, given as a `FunPtr`.-connectSignalFunPtr :: GObject o =>-                  o -> String -> FunPtr a -> SignalConnectMode -> IO SignalHandlerId-connectSignalFunPtr object signal fn mode = do-  let flags = case mode of-                SignalConnectAfter -> 1-                SignalConnectBefore -> 0-  withCString signal $ \csignal ->-    withManagedPtr object $ \objPtr ->-        g_signal_connect_data objPtr csignal fn (castFunPtrToPtr fn) safeFreeFunPtrPtr flags---- | Connection information for a "notify" signal indicating that a--- specific property changed (see `PropertyNotify` for the relevant--- constructor).-data GObjectNotifySignalInfo (propName :: Symbol)-instance KnownSymbol propName =>-    SignalInfo (GObjectNotifySignalInfo propName) where-  type HaskellCallbackType (GObjectNotifySignalInfo propName) = GObjectNotifyCallback-  connectSignal = connectGObjectNotify (symbolVal (Proxy :: Proxy propName))---- | Type for a `GObject` `notify` callback.-type GObjectNotifyCallback = GParamSpec -> IO ()--gobjectNotifyCallbackWrapper ::-    GObjectNotifyCallback -> Ptr () -> Ptr GParamSpec -> Ptr () -> IO ()-gobjectNotifyCallbackWrapper _cb _ pspec _ = do-    pspec' <- newGParamSpecFromPtr pspec-    _cb  pspec'--type GObjectNotifyCallbackC = Ptr () -> Ptr GParamSpec -> Ptr () -> IO ()--foreign import ccall "wrapper"-    mkGObjectNotifyCallback :: GObjectNotifyCallbackC -> IO (FunPtr GObjectNotifyCallbackC)---- | Connect the given notify callback for a GObject.-connectGObjectNotify :: forall o i. GObject o =>-                        String ->-                        SignalProxy o (i :: *) ->-                        o -> GObjectNotifyCallback ->-                        SignalConnectMode -> IO SignalHandlerId-connectGObjectNotify propName _ obj cb mode = do-  cb' <- mkGObjectNotifyCallback (gobjectNotifyCallbackWrapper cb)-  let signalName = "notify::" ++ propName-  connectSignalFunPtr obj signalName cb' mode
− src/Data/GI/Base/Utils.hsc
@@ -1,200 +0,0 @@-{-# LANGUAGE ScopedTypeVariables, TupleSections, OverloadedStrings #-}-{- | Assorted utility functions for bindings. -}-module Data.GI.Base.Utils-    ( whenJust-    , maybeM-    , maybeFromPtr-    , mapFirst-    , mapFirstA-    , mapSecond-    , mapSecondA-    , convertIfNonNull-    , convertFunPtrIfNonNull-    , callocBytes-    , callocBoxedBytes-    , callocMem-    , allocBytes-    , allocMem-    , freeMem-    , ptr_to_g_free-    , memcpy-    , safeFreeFunPtr-    , safeFreeFunPtrPtr-    , maybeReleaseFunPtr-    , checkUnexpectedReturnNULL-    , checkUnexpectedNothing-    ) where--#include <glib-object.h>--#if !MIN_VERSION_base(4,8,0)-import Control.Applicative (Applicative, pure, (<$>), (<*>))-#endif-import Control.Exception (throwIO)-import Control.Monad (void)--import qualified Data.Text as T-import Data.Monoid ((<>))-import Data.Word--import Foreign (peek)-import Foreign.C.Types (CSize(..))-import Foreign.Ptr (Ptr, nullPtr, FunPtr, nullFunPtr, freeHaskellFunPtr)-import Foreign.Storable (Storable(..))--import Data.GI.Base.BasicTypes (GType(..), CGType, BoxedObject(..),-                                UnexpectedNullPointerReturn(..))---- | When the given value is of "Just a" form, execute the given action,--- otherwise do nothing.-whenJust :: Monad m => Maybe a -> (a -> m ()) -> m ()-whenJust (Just v) f = f v-whenJust Nothing _ = return ()---- | Like `Control.Monad.maybe`, but for actions on a monad, and with--- slightly different argument order.-maybeM :: Monad m => b -> Maybe a -> (a -> m b) -> m b-maybeM d Nothing _ = return d-maybeM _ (Just v) action = action v---- | Check if the pointer is `nullPtr`, and wrap it on a `Maybe`--- accordingly.-maybeFromPtr :: Ptr a -> Maybe (Ptr a)-maybeFromPtr ptr = if ptr == nullPtr-                   then Nothing-                   else Just ptr---- | Given a function and a list of two-tuples, apply the function to--- every first element of the tuples.-mapFirst :: (a -> c) -> [(a,b)] -> [(c,b)]-mapFirst _ [] = []-mapFirst f ((x,y) : rest) = (f x, y) : mapFirst f rest---- | Same for the second element.-mapSecond :: (b -> c) -> [(a,b)] -> [(a,c)]-mapSecond _ [] = []-mapSecond f ((x,y) : rest) = (x, f y) : mapSecond f rest---- | Applicative version of `mapFirst`.-mapFirstA :: Applicative f => (a -> f c) -> [(a,b)] -> f [(c,b)]-mapFirstA _ [] = pure []-mapFirstA f ((x,y) : rest) = (:) <$> ((,y) <$> f x) <*> mapFirstA f rest---- | Applicative version of `mapSecond`.-mapSecondA :: Applicative f => (b -> f c) -> [(a,b)] -> f [(a,c)]-mapSecondA _ [] = pure []-mapSecondA f ((x,y) : rest) = (:) <$> ((x,) <$> f y) <*> mapSecondA f rest---- | Apply the given conversion action to the given pointer if it is--- non-NULL, otherwise return `Nothing`.-convertIfNonNull :: Ptr a -> (Ptr a -> IO b) -> IO (Maybe b)-convertIfNonNull ptr convert = if ptr == nullPtr-                               then return Nothing-                               else Just <$> convert ptr---- | Apply the given conversion action to the given function pointer--- if it is non-NULL, otherwise return `Nothing`.-convertFunPtrIfNonNull :: FunPtr a -> (FunPtr a -> IO b) -> IO (Maybe b)-convertFunPtrIfNonNull ptr convert = if ptr == nullFunPtr-                                     then return Nothing-                                     else Just <$> convert ptr--foreign import ccall "g_malloc0" g_malloc0 ::-    #{type gsize} -> IO (Ptr a)---- | Make a zero-filled allocation using the GLib allocator.-{-# INLINE callocBytes #-}-callocBytes :: Int -> IO (Ptr a)-callocBytes n =  g_malloc0 (fromIntegral n)---- | Make a zero-filled allocation of enough size to hold the given--- `Storable` type, using the GLib allocator.-{-# INLINE callocMem #-}-callocMem :: forall a. Storable a => IO (Ptr a)-callocMem = g_malloc0 $ (fromIntegral . sizeOf) (undefined :: a)--foreign import ccall "g_boxed_copy" g_boxed_copy ::-    CGType -> Ptr a -> IO (Ptr a)---- | Make a zero filled allocation of n bytes for a boxed object. The--- difference with a normal callocBytes is that the returned memory is--- allocated using whatever memory allocator g_boxed_copy uses, which--- in particular may well be different from a plain g_malloc. In--- particular g_slice_alloc is often used for allocating boxed--- objects, which are then freed using g_slice_free.-callocBoxedBytes :: forall a. BoxedObject a => Int -> IO (Ptr a)-callocBoxedBytes n = do-  ptr <- callocBytes n-  GType cgtype <- boxedType (undefined :: a)-  result <- g_boxed_copy cgtype ptr-  freeMem ptr-  return result--foreign import ccall "g_malloc" g_malloc ::-    #{type gsize} -> IO (Ptr a)---- | Allocate the given number of bytes using the GLib allocator.-{-# INLINE allocBytes #-}-allocBytes :: Integral a => a -> IO (Ptr b)-allocBytes n = g_malloc (fromIntegral n)---- | Allocate space for the given `Storable` using the GLib allocator.-{-# INLINE allocMem #-}-allocMem :: forall a. Storable a => IO (Ptr a)-allocMem = g_malloc $ (fromIntegral . sizeOf) (undefined :: a)---- | A wrapper for `g_free`.-foreign import ccall "g_free" freeMem :: Ptr a -> IO ()---- | Pointer to `g_free`.-foreign import ccall "&g_free" ptr_to_g_free :: FunPtr (Ptr a -> IO ())--foreign import ccall unsafe "string.h memcpy" _memcpy :: Ptr a -> Ptr b -> CSize -> IO (Ptr ())---- | Copy memory into a destination (in the first argument) from a--- source (in the second argument).-{-# INLINE memcpy #-}-memcpy :: Ptr a -> Ptr b -> Int -> IO ()-memcpy dest src n = void $ _memcpy dest src (fromIntegral n)---- | Same as freeHaskellFunPtr, but it does nothing when given a--- nullPtr.-foreign import ccall "safeFreeFunPtr" safeFreeFunPtr ::-    Ptr a -> IO ()---- | A pointer to `safeFreeFunPtr`.-foreign import ccall "& safeFreeFunPtr" safeFreeFunPtrPtr ::-    FunPtr (Ptr a -> IO ())---- | If given a pointer to the memory location, free the `FunPtr` at--- that location, and then the pointer itself. Useful for freeing the--- memory associated to callbacks which are called just once, with no--- destroy notification.-maybeReleaseFunPtr :: Maybe (Ptr (FunPtr a)) -> IO ()-maybeReleaseFunPtr Nothing = return ()-maybeReleaseFunPtr (Just f) = do-  peek f >>= freeHaskellFunPtr-  freeMem f---- | Check that the given pointer is not NULL. If it is, raise a--- `UnexpectedNullPointerReturn` exception.-checkUnexpectedReturnNULL :: T.Text -> Ptr a -> IO ()-checkUnexpectedReturnNULL fnName ptr-    | ptr == nullPtr =-        throwIO (UnexpectedNullPointerReturn {-                   nullPtrErrorMsg = "Received unexpected nullPtr in \""-                                     <> fnName <> "\"."-                 })-    | otherwise = return ()---- | An annotated version of `fromJust`, which raises a--- `UnexpectedNullPointerReturn` in case it encounters a `Nothing`.-checkUnexpectedNothing :: T.Text -> IO (Maybe a) -> IO a-checkUnexpectedNothing fnName action = do-  result <- action-  case result of-    Just r -> return r-    Nothing -> throwIO (UnexpectedNullPointerReturn {-                 nullPtrErrorMsg = "Received unexpected nullPtr in \""-                                     <> fnName <> "\"."-                 })
− src/c/hsgclosure.c
@@ -1,93 +0,0 @@-#define _GNU_SOURCE--/* GHC's semi-public Rts API */-#include <Rts.h>--#include <stdlib.h>--#include <glib-object.h>--int check_object_type(void *instance, GType type)-{-  int result;--  if (instance != NULL) {-     result = !!G_TYPE_CHECK_INSTANCE_TYPE(instance, type);-  } else {-    result = 0;-    fprintf(stderr, "Check failed: got a null pointer\n");-  }--  return result;-}--static int print_debug_info ()-{-  static int __print_debug_info = -1;--  if (__print_debug_info == -1) {-    __print_debug_info = getenv ("HASKELL_GI_DEBUG_MEM") != NULL;-  }--  return __print_debug_info;-}--/* Auxiliary function for freeing boxed types */-void boxed_free_helper (GType gtype, void *boxed)-{-  if (print_debug_info()) {-    fprintf(stderr, "Freeing a boxed object at %p\n", boxed);-    fprintf(stderr, "\tIt is of type %s\n", g_type_name(gtype));-  }--  g_boxed_free (gtype, boxed);--  if (print_debug_info()) {-    fprintf(stderr, "\tdone\n");-  }-}--void dbg_g_object_unref (GObject *obj)-{-  GType gtype;--  if (print_debug_info()) {-    fprintf(stderr, "Freeing a GObject at %p\n", obj);-    gtype = G_TYPE_FROM_INSTANCE (obj);-    fprintf(stderr, "\tIt is of type %s\n", g_type_name(gtype));-    fprintf(stderr, "\tIts refcount before unref is %d\n",-            (int)obj->ref_count);-  }--  g_object_unref(obj);--  if (print_debug_info()) {-    fprintf(stderr, "\tdone\n");-  }-}--gpointer dbg_g_object_newv (GType gtype, guint n_params, GParameter *params)-{-  gpointer result;--  if (print_debug_info()) {-    fprintf(stderr, "Creating a new GObject of type %s\n",-            g_type_name(gtype));-  }--  result = g_object_newv (gtype, n_params, params);--  if (print_debug_info()) {-    fprintf(stderr, "\tdone, got a pointer at %p\n", result);-  }--  return result;-}--/* Same as freeHaskellFunctionPtr, but it does nothing when given a-   null pointer, instead of crashing */-void safeFreeFunPtr(void *ptr)-{-  if (ptr != NULL)-    freeHaskellFunctionPtr(ptr);-}