DBus-0.1: demo/Monitor.hs
{-# OPTIONS -fglasgow-exts #-}
-- ghc --make -ldbus-1 -o monitor Monitor.hs
import qualified DBus
import qualified DBus.Connection
import qualified DBus.Message
import Control.Exception(catchDyn)
import Data.Int
import Data.Word
import Data.Dynamic
import DBus.Message(Arg, variant)
import DBus.Connection(withConnection, readWriteDispatch, addFilter, addMatch, BusType(Session))
type Variant = DBus.Message.Variant
type Bus = DBus.Connection.Connection
type NotifyArgs = (String, Word32, String, String, String,
[String], DBus.Message.Dict String Variant, Int32)
main :: IO ()
main = do
let loop bus = (readWriteDispatch bus (-1) >> loop bus)
withConnection Session $ \bus -> do
addFilter bus $ \msg -> do
path <- DBus.Message.getPath msg
iface <- DBus.Message.getInterface msg
member <- DBus.Message.getMember msg
src <- DBus.Message.getSender msg
dst <- DBus.Message.getDestination msg
errname <- DBus.Message.getErrorName msg
sig <- DBus.Message.getSignature msg
t <- DBus.Message.getType msg
let cstr (Just s) = s
cstr (Nothing) = "null"
let s = "sender="++ cstr src ++ " -> dest="++cstr dst ++ " sig=" ++ sig
let ms = s ++ " path=" ++ cstr path ++ "; interface="++ cstr iface
++ "; member=" ++ cstr member ++ "\n"
case t of
DBus.Message.MethodCall -> putStr $ "Call " ++ ms
DBus.Message.MethodReturn -> putStr $ "Return " ++ s ++ "\n"
DBus.Message.Error -> putStr $ "Error " ++ s ++ " errname=" ++ cstr errname ++ "\n"
DBus.Message.Signal -> putStr $ "Signal " ++ ms
DBus.Message.Other x -> putStr $ "Other: " ++ (show x) ++ ms
vars <- variantArgs msg
mapM_ (\var -> do
putStr "\t"
print var)
vars
return True
addMatch bus False "type='method_call'"
addMatch bus False "type='method_return'"
addMatch bus False "type='error'"
addMatch bus False "type='signal'"
loop bus
data Tagged = I32 Int32 | W32 Word32 | S String | A [Dynamic] | B Bool | E [Dynamic] [Dynamic] | Invalid
tag :: Dynamic -> Tagged
tag dyn =
case fromDynamic dyn of
Just (i :: Int32) -> I32 i
Nothing ->
case fromDynamic dyn of
Just (word :: Word32) -> W32 word
Nothing ->
case fromDynamic dyn of
Just (s :: String) -> S s
Nothing ->
case fromDynamic dyn of
Just (arr :: [Dynamic]) -> A arr
Nothing ->
case fromDynamic dyn of
Just (b :: Bool) -> B b
Nothing ->
case fromDynamic dyn of
Just (a, b) -> E a b
Nothing -> Invalid
toVariant :: Dynamic -> Variant
toVariant dyn =
case tag dyn of
I32 i -> variant i
W32 w -> variant w
S s -> variant s
A arr -> variant (map toVariant arr)
B b -> variant (if b then (1 :: Int32) else 0)
E a b -> variant (map toVariant a, map toVariant b)
Invalid -> variant "<invalid>"
variantArgs msg = do
(args :: [Dynamic]) <- DBus.Message.args msg
return $ map toVariant args
{-
variantArgs msg =
let load msg =
do args <- DBus.Message.args msg;
return args
try cmp els =
catch (do val <- cmp
return $ DBus.Message.variant val)
(\err -> els)
in try ((load msg) :: IO [Dynamic]) $
try ((load msg) :: IO Int32) $
try ((load msg) :: IO Word32) $
try ((load msg) :: IO String) $
try ((load msg) :: IO ()) $
try ((load msg) :: IO [Int32]) $
try ((load msg) :: IO [Word32]) $
try ((load msg) :: IO [String]) $
try ((load msg) :: IO [()]) $
try ((load msg) :: IO NotifyArgs) $
try ((load msg) :: IO Variant)
(putStr "variantArgs failed\n" >> fail "Cannot figure out the type\n")
-}
{-
snoop :: Arg a => DBus.Message.Message -> IO a
snoop msg = do
args <- DBus.Message.args msg
print (DBus.Message.variant args)
return args
eat :: IO a -> IO ()
eat cmp = cmp >> return ()
try :: IO a -> IO () -> IO ()
try cmp els =
catch (eat cmp) (\err -> els)
-}