-- Copyright (C) 2009-2012 John Millikin <jmillikin@gmail.com>---- 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 <http://www.gnu.org/licenses/>.-- | Basic types, useful to every D-Bus application.---- Authors of client applications should import "DBus.Client", which provides-- an easy RPC-oriented interface to D-Bus methods and signals.moduleDBus(-- * MessagesMessage-- ** Method calls,MethodCall,methodCall,methodCallPath,methodCallInterface,methodCallMember,methodCallSender,methodCallDestination,methodCallAutoStart,methodCallReplyExpected,methodCallBody-- ** Method returns,MethodReturn,methodReturn,methodReturnSerial,methodReturnSender,methodReturnDestination,methodReturnBody-- ** Method errors,MethodError,methodError,methodErrorName,methodErrorSerial,methodErrorSender,methodErrorDestination,methodErrorBody,methodErrorMessage-- ** Signals,Signal,signal,signalPath,signalMember,signalInterface,signalSender,signalDestination,signalBody-- ** Received messages,ReceivedMessage(ReceivedMethodCall,ReceivedMethodReturn,ReceivedMethodError,ReceivedSignal),receivedMessageSerial,receivedMessageSender,receivedMessageBody-- * Variants,Variant,IsVariant(..),variantType,IsAtom,IsValue,typeOf-- * Signatures,Signature,Type(..),signature,signature_,signatureTypes,formatSignature,parseSignature-- * Object paths,ObjectPath,objectPath_,formatObjectPath,parseObjectPath-- * Names-- ** Interface names,InterfaceName,interfaceName_,formatInterfaceName,parseInterfaceName-- ** Member names,MemberName,memberName_,formatMemberName,parseMemberName-- ** Error names,ErrorName,errorName_,formatErrorName,parseErrorName-- ** Bus names,BusName,busName_,formatBusName,parseBusName-- * Non-native containers-- ** Structures,Structure,structureItems-- ** Arrays,Array,arrayItems-- ** Dictionaries,Dictionary,dictionaryItems-- * Addresses,Address,addressMethod,addressParameters,address,formatAddress,formatAddresses,parseAddress,parseAddresses,getSystemAddress,getSessionAddress,getStarterAddress-- * Message marshaling,Endianness(..)-- ** Marshal,marshal,MarshalError,marshalErrorMessage-- ** Unmarshal,unmarshal,UnmarshalError,unmarshalErrorMessage-- ** Message serials,Serial,serialValue,firstSerial,nextSerial-- * D-Bus UUIDs,UUID,formatUUID,randomUUID)whereimportControl.Monad(replicateM)importqualifiedData.ByteString.Char8asChar8importData.Word(Word16)importSystem.Random(randomRIO)importText.Printf(printf)importDBus.AddressimportDBus.MessageimportqualifiedDBus.TypesimportDBus.Typeshiding(typeOf)importDBus.Wire-- | Get the D-Bus type corresponding to the given Haskell value. The value-- may be @undefined@.typeOf::IsValuea=>a->TypetypeOf=DBus.Types.typeOf-- | Construct a new 'MethodCall' for the given object, interface, and method.---- Use fields such as 'methodCallDestination' and 'methodCallBody' to populate-- a 'MethodCall'.---- @--{-\# LANGUAGE OverloadedStrings \#-}----methodCall \"/\" \"org.example.Math\" \"Add\"-- { 'methodCallDestination' = Just \"org.example.Calculator\"-- , 'methodCallBody' = ['toVariant' (1 :: Int32), 'toVariant' (2 :: Int32)]-- }-- @methodCall::ObjectPath->InterfaceName->MemberName->MethodCallmethodCallpathifacemember=MethodCallpath(Justiface)memberNothingNothingTrueTrue[]-- | Construct a new 'MethodReturn', in reply to a method call with the given-- serial.---- Use fields such as 'methodReturnBody' to populate a 'MethodReturn'.methodReturn::Serial->MethodReturnmethodReturns=MethodReturnsNothingNothing[]-- | Construct a new 'MethodError', in reply to a method call with the given-- serial.---- Use fields such as 'methodErrorBody' to populate a 'MethodError'.methodError::Serial->ErrorName->MethodErrormethodErrorsname=MethodErrornamesNothingNothing[]-- | Construct a new 'Signal' for the given object, interface, and signal name.---- Use fields such as 'signalBody' to populate a 'Signal'.signal::ObjectPath->InterfaceName->MemberName->Signalsignalpathifacemember=SignalpathifacememberNothingNothing[]-- | No matter what sort of message was received, get its serial.receivedMessageSerial::ReceivedMessage->SerialreceivedMessageSerial(ReceivedMethodCalls_)=sreceivedMessageSerial(ReceivedMethodReturns_)=sreceivedMessageSerial(ReceivedMethodErrors_)=sreceivedMessageSerial(ReceivedSignals_)=sreceivedMessageSerial(ReceivedUnknowns_)=s-- | No matter what sort of message was received, get its sender (if provided).receivedMessageSender::ReceivedMessage->MaybeBusNamereceivedMessageSender(ReceivedMethodCall_msg)=methodCallSendermsgreceivedMessageSender(ReceivedMethodReturn_msg)=methodReturnSendermsgreceivedMessageSender(ReceivedMethodError_msg)=methodErrorSendermsgreceivedMessageSender(ReceivedSignal_msg)=signalSendermsgreceivedMessageSender(ReceivedUnknown_msg)=unknownMessageSendermsg-- | No matter what sort of message was received, get its body (if provided).receivedMessageBody::ReceivedMessage->[Variant]receivedMessageBody(ReceivedMethodCall_msg)=methodCallBodymsgreceivedMessageBody(ReceivedMethodReturn_msg)=methodReturnBodymsgreceivedMessageBody(ReceivedMethodError_msg)=methodErrorBodymsgreceivedMessageBody(ReceivedSignal_msg)=signalBodymsgreceivedMessageBody(ReceivedUnknown_msg)=unknownMessageBodymsg-- | Convert a 'Message' into a 'Char8.ByteString'. Although unusual, it is-- possible for marshaling to fail; if this occurs, an error will be-- returned instead.marshal::Messagemsg=>Endianness->Serial->msg->EitherMarshalErrorChar8.ByteStringmarshal=marshalMessage-- | Parse a 'Char8.ByteString' into a 'ReceivedMessage'. The result can be-- inspected to see what type of message was parsed. Unknown message types-- can still be parsed successfully, as long as they otherwise conform to-- the D-Bus standard.unmarshal::Char8.ByteString->EitherUnmarshalErrorReceivedMessageunmarshal=unmarshalMessage-- | A D-Bus UUID is 128 bits of data, usually randomly generated. They are-- used for identifying unique server instances to clients.---- Older versions of the D-Bus spec also called these values /GUIDs/.---- D-Bus UUIDs are not the same as the RFC-standardized UUIDs or GUIDs.newtypeUUID=UUIDChar8.ByteStringderiving(Eq,Ord,Show)-- | Format a D-Bus UUID as hex-encoded ASCII.formatUUID::UUID->StringformatUUID(UUIDbytes)=Char8.unpackbytes-- | Generate a random D-Bus UUID. This value is suitable for use in a-- randomly-allocated address, or as a listener's socket address-- @\"guid\"@ parameter.randomUUID::IOUUIDrandomUUID=do-- The version of System.Random bundled with ghc < 7.2 doesn't define-- instances for any of the fixed-length word types, so we imitate-- them using the instance for Int.---- 128 bits is 8 16-bit integers. We use chunks of 16 instead of 32-- because Int is not guaranteed to be able to store a Word32.lethexInt16i=printf"%04x"(i::Int)int16s<-replicateM8(randomRIO(0,fromIntegral(maxBound::Word16)))return(UUID(Char8.pack(concatMaphexInt16int16s)))