{-# LANGUAGE OverloadedStrings #-} -- Copyright (C) 2009-2011 John Millikin -- -- Licensed under the Apache License, Version 2.0 (the "License"); -- you may not use this file except in compliance with the License. -- You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- -- Unless required by applicable law or agreed to in writing, software -- distributed under the License is distributed on an "AS IS" BASIS, -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- See the License for the specific language governing permissions and -- limitations under the License. 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 I.In -> "IN " I.Out -> "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 ""