module System.Glib.Signals (
Signal(Signal),
on, after,
SignalName,
GSignalMatchType(..),
ConnectAfter,
ConnectId(ConnectId),
signalDisconnect,
signalBlock,
signalBlockMatched,
signalUnblock,
signalStopEmission,
disconnect,
GClosure,
connectGeneric,
) where
import Control.Monad (liftM)
import System.Glib.FFI
import System.Glib.GType
import System.Glib.Flags
import System.Glib.GObject
newtype Signal object handler =
Signal (Bool -> object -> handler -> IO (ConnectId object))
on ::
object
-> Signal object callback
-> callback
-> IO (ConnectId object)
on object (Signal connect) handler = connect False object handler
after ::
object
-> Signal object callback
-> callback
-> IO (ConnectId object)
after object (Signal connect) handler = connect True object handler
type ConnectAfter = Bool
type SignalName = String
data GObjectClass o => ConnectId o = ConnectId (CULong) o
disconnect :: GObjectClass obj => ConnectId obj -> IO ()
disconnect = signalDisconnect
signalDisconnect :: GObjectClass obj => ConnectId obj -> IO ()
signalDisconnect (ConnectId handler obj) =
withForeignPtr ((unGObject.toGObject) obj) $ \objPtr ->
g_signal_handler_disconnect (castPtr objPtr) handler
signalBlock :: GObjectClass obj => ConnectId obj -> IO ()
signalBlock (ConnectId handler obj) =
withForeignPtr ((unGObject.toGObject) obj) $ \objPtr ->
g_signal_handler_block (castPtr objPtr) handler
data GSignalMatchType = SignalMatchId
| SignalMatchDetail
| SignalMatchClosure
| SignalMatchFunc
| SignalMatchData
| SignalMatchUnblocked
deriving (Eq,Ord,Bounded)
instance Enum GSignalMatchType where
fromEnum SignalMatchId = 1
fromEnum SignalMatchDetail = 2
fromEnum SignalMatchClosure = 4
fromEnum SignalMatchFunc = 8
fromEnum SignalMatchData = 16
fromEnum SignalMatchUnblocked = 32
toEnum 1 = SignalMatchId
toEnum 2 = SignalMatchDetail
toEnum 4 = SignalMatchClosure
toEnum 8 = SignalMatchFunc
toEnum 16 = SignalMatchData
toEnum 32 = SignalMatchUnblocked
toEnum unmatched = error ("GSignalMatchType.toEnum: Cannot match " ++ show unmatched)
succ SignalMatchId = SignalMatchDetail
succ SignalMatchDetail = SignalMatchClosure
succ SignalMatchClosure = SignalMatchFunc
succ SignalMatchFunc = SignalMatchData
succ SignalMatchData = SignalMatchUnblocked
succ _ = undefined
pred SignalMatchDetail = SignalMatchId
pred SignalMatchClosure = SignalMatchDetail
pred SignalMatchFunc = SignalMatchClosure
pred SignalMatchData = SignalMatchFunc
pred SignalMatchUnblocked = SignalMatchData
pred _ = undefined
enumFromTo x y | fromEnum x == fromEnum y = [ y ]
| otherwise = x : enumFromTo (succ x) y
enumFrom x = enumFromTo x SignalMatchUnblocked
enumFromThen _ _ = error "Enum GSignalMatchType: enumFromThen not implemented"
enumFromThenTo _ _ _ = error "Enum GSignalMatchType: enumFromThenTo not implemented"
instance Flags GSignalMatchType
signalBlockMatched :: GObjectClass obj
=> obj
-> [GSignalMatchType]
-> SignalName
-> GType
-> Quark
-> Maybe GClosure
-> Maybe (Ptr ())
-> Maybe (Ptr ())
-> IO Int
signalBlockMatched obj mask sigName gType quark closure func userData = do
sigId <- withCString sigName $ \strPtr ->
g_signal_lookup strPtr gType
liftM fromIntegral $ withForeignPtr (unGObject $ toGObject obj) $ \objPtr ->
g_signal_handlers_block_matched
(castPtr objPtr)
(fromIntegral $ fromFlags mask)
sigId
quark
(maybe nullPtr (\(GClosure p) -> castPtr p) closure)
(maybe nullPtr id func)
(maybe nullPtr id userData)
signalUnblock :: GObjectClass obj => ConnectId obj -> IO ()
signalUnblock (ConnectId handler obj) =
withForeignPtr ((unGObject.toGObject) obj) $ \objPtr ->
g_signal_handler_unblock (castPtr objPtr) handler
signalStopEmission :: GObjectClass obj => obj -> SignalName -> IO ()
signalStopEmission obj sigName =
withForeignPtr ((unGObject.toGObject) obj) $ \objPtr ->
withCString sigName $ \strPtr ->
g_signal_stop_emission_by_name (castPtr objPtr) strPtr
newtype GClosure = GClosure (Ptr (GClosure))
connectGeneric :: GObjectClass obj =>
SignalName
-> ConnectAfter
-> obj
-> handler
-> IO (ConnectId obj)
connectGeneric signal after obj user = do
sptr <- newStablePtr user
gclosurePtr <- gtk2hs_closure_new sptr
sigId <-
withCString signal $ \signalPtr ->
withForeignPtr ((unGObject.toGObject) obj) $ \objPtr ->
(\arg1 arg2 (GClosure arg3) arg4 -> g_signal_connect_closure arg1 arg2 arg3 arg4)
(castPtr objPtr)
signalPtr
(GClosure gclosurePtr)
(fromBool after)
return $ ConnectId sigId obj
foreign import ccall unsafe "gtk2hs_closure_new"
gtk2hs_closure_new :: StablePtr a -> IO (Ptr GClosure)
foreign import ccall safe "g_signal_handler_disconnect"
g_signal_handler_disconnect :: ((Ptr ()) -> (CULong -> (IO ())))
foreign import ccall safe "g_signal_handler_block"
g_signal_handler_block :: ((Ptr ()) -> (CULong -> (IO ())))
foreign import ccall safe "g_signal_lookup"
g_signal_lookup :: ((Ptr CChar) -> (CULong -> (IO CUInt)))
foreign import ccall safe "g_signal_handlers_block_matched"
g_signal_handlers_block_matched :: ((Ptr ()) -> (CInt -> (CUInt -> (CUInt -> ((Ptr ()) -> ((Ptr ()) -> ((Ptr ()) -> (IO CUInt))))))))
foreign import ccall safe "g_signal_handler_unblock"
g_signal_handler_unblock :: ((Ptr ()) -> (CULong -> (IO ())))
foreign import ccall safe "g_signal_stop_emission_by_name"
g_signal_stop_emission_by_name :: ((Ptr ()) -> ((Ptr CChar) -> (IO ())))
foreign import ccall safe "g_signal_connect_closure"
g_signal_connect_closure :: ((Ptr ()) -> ((Ptr CChar) -> ((Ptr GClosure) -> (CInt -> (IO CULong)))))