{-# LANGUAGE OverloadedStrings #-} -- Copyright (C) 2009-2011 John Millikin -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . module Main (main) where import Control.Monad (when) import Data.String (fromString) import System.Environment (getArgs, getProgName) import System.Exit (exitFailure) import System.IO (hPutStrLn, stderr) import DBus import DBus.Client import qualified DBus.Introspection as I main :: IO () main = do args <- getArgs (service, path) <- case args of a1:a2:_ -> return (fromString a1, fromString a2) _ -> do name <- getProgName hPutStrLn stderr ("Usage: " ++ name ++ " ") exitFailure client <- connectSession printObj (introspect client service) path introspect :: Client -> BusName -> ObjectPath -> IO I.Object introspect client service path = do reply <- call_ client (methodCall path "org.freedesktop.DBus.Introspectable" "Introspect") { methodCallDestination = Just service } let Just xml = fromVariant (methodReturnBody reply !! 0) case I.parseXML path xml of Just info -> return info Nothing -> error ("Invalid introspection XML: " ++ show xml) -- most of this stuff is just boring text formatting printObj :: (ObjectPath -> IO I.Object) -> ObjectPath -> IO () printObj get path = do obj <- get path putStrLn (formatObjectPath path) mapM_ printIface (I.objectInterfaces obj) putStrLn "" mapM_ (printObj get) [I.objectPath x | x <- I.objectChildren obj] printIface :: I.Interface -> IO () printIface iface = do putStr " " putStrLn (formatInterfaceName (I.interfaceName iface)) mapM_ printMethod (I.interfaceMethods iface) mapM_ printSignal (I.interfaceSignals iface) mapM_ printProperty (I.interfaceProperties iface) putStrLn "" printMethod :: I.Method -> IO () printMethod method = do putStr " method " putStrLn (formatMemberName (I.methodName method)) mapM_ printMethodArg (I.methodArgs method) printMethodArg :: I.MethodArg -> IO () printMethodArg arg = do let dir = case I.methodArgDirection arg of d | d == I.directionIn -> "IN " d | d == I.directionOut -> "OUT" _ -> " " putStr (" [" ++ dir ++ " ") putStr (show (formatSignature (signature_ [I.methodArgType arg])) ++ "] ") putStrLn (I.methodArgName arg) printSignal :: I.Signal -> IO () printSignal sig = do putStr " signal " putStrLn (formatMemberName (I.signalName sig)) mapM_ printSignalArg (I.signalArgs sig) printSignalArg :: I.SignalArg -> IO () printSignalArg arg = do putStr " [" putStr (show (formatSignature (signature_ [I.signalArgType arg])) ++ "] ") putStrLn (I.signalArgName arg) printProperty :: I.Property -> IO () printProperty prop = do putStr " property " putStr (show (formatSignature (signature_ [I.propertyType prop])) ++ " ") putStrLn (I.propertyName prop) putStr " " when (I.propertyRead prop) (putStr "Read") when (I.propertyWrite prop) (putStr "Write") putStrLn ""