{-# LANGUAGE OverloadedStrings #-}
module XMonad.DBus (connect,subscribe,subscribeToPath,bodyToString,requestAccess,send,sendToPath) where

import Data.Maybe (mapMaybe)
import qualified DBus as D
import qualified DBus.Client as DC

busName :: BusName
busName = BusName
"org.XMonad.DBus"
interface :: InterfaceName
interface = InterfaceName
"org.XMonad.DBus"
pathPrefix :: [Char]
pathPrefix = [Char]
"/org/XMonad"
pathPrefixObjectPath :: ObjectPath
pathPrefixObjectPath = [Char] -> ObjectPath
D.objectPath_ [Char]
pathPrefix
member :: MemberName
member = MemberName
"Update"

connect :: IO DC.Client
connect :: IO Client
connect = IO Client
DC.connectSession

requestAccess :: Client -> IO RequestNameReply
requestAccess Client
c = Client -> BusName -> [RequestNameFlag] -> IO RequestNameReply
DC.requestName Client
c BusName
busName [RequestNameFlag
DC.nameAllowReplacement, RequestNameFlag
DC.nameReplaceExisting, RequestNameFlag
DC.nameDoNotQueue]


matchAnyPath :: DC.MatchRule
matchAnyPath :: MatchRule
matchAnyPath = MatchRule
DC.matchAny {
            matchInterface :: Maybe InterfaceName
DC.matchInterface = InterfaceName -> Maybe InterfaceName
forall a. a -> Maybe a
Just InterfaceName
interface,
            matchPathNamespace :: Maybe ObjectPath
DC.matchPathNamespace = ObjectPath -> Maybe ObjectPath
forall a. a -> Maybe a
Just ObjectPath
pathPrefixObjectPath,
            matchMember :: Maybe MemberName
DC.matchMember = MemberName -> Maybe MemberName
forall a. a -> Maybe a
Just MemberName
member
        }

matchPath :: String -> DC.MatchRule
matchPath :: [Char] -> MatchRule
matchPath [Char]
name = MatchRule
DC.matchAny {
            matchInterface :: Maybe InterfaceName
DC.matchInterface = InterfaceName -> Maybe InterfaceName
forall a. a -> Maybe a
Just InterfaceName
interface,
            matchPath :: Maybe ObjectPath
DC.matchPath = ([Char] -> Maybe ObjectPath
forall (m :: * -> *). MonadThrow m => [Char] -> m ObjectPath
D.parseObjectPath ([Char] -> Maybe ObjectPath) -> [Char] -> Maybe ObjectPath
forall a b. (a -> b) -> a -> b
$ [Char]
pathPrefix[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"/"[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
name),
            matchMember :: Maybe MemberName
DC.matchMember = MemberName -> Maybe MemberName
forall a. a -> Maybe a
Just MemberName
member
        }

subscribe :: Client -> (Signal -> IO ()) -> IO SignalHandler
subscribe Client
c Signal -> IO ()
handler = Client -> MatchRule -> (Signal -> IO ()) -> IO SignalHandler
DC.addMatch Client
c MatchRule
matchAnyPath Signal -> IO ()
handler
subscribeToPath :: Client -> [Char] -> (Signal -> IO ()) -> IO SignalHandler
subscribeToPath Client
c [Char]
path Signal -> IO ()
handler = Client -> MatchRule -> (Signal -> IO ()) -> IO SignalHandler
DC.addMatch Client
c ([Char] -> MatchRule
matchPath [Char]
path) Signal -> IO ()
handler

bodyToString :: D.Signal -> [String]
bodyToString :: Signal -> [[Char]]
bodyToString Signal
s = (Variant -> Maybe [Char]) -> [Variant] -> [[Char]]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Variant -> Maybe [Char]
forall a. IsVariant a => Variant -> Maybe a
D.fromVariant (Signal -> [Variant]
D.signalBody Signal
s)


send :: DC.Client -> String -> IO ()
send :: Client -> [Char] -> IO ()
send Client
c [Char]
s = Client -> Signal -> IO ()
DC.emit Client
c (Signal -> IO ()) -> Signal -> IO ()
forall a b. (a -> b) -> a -> b
$ (ObjectPath -> InterfaceName -> MemberName -> Signal
D.signal ObjectPath
pathPrefixObjectPath InterfaceName
interface MemberName
member) {
    signalBody :: [Variant]
D.signalBody = [[Char] -> Variant
forall a. IsVariant a => a -> Variant
D.toVariant [Char]
s]
    }

sendToPath :: DC.Client -> String -> String -> IO ()
sendToPath :: Client -> [Char] -> [Char] -> IO ()
sendToPath Client
c [Char]
p [Char]
s = Client -> Signal -> IO ()
DC.emit Client
c (Signal -> IO ()) -> Signal -> IO ()
forall a b. (a -> b) -> a -> b
$ (ObjectPath -> InterfaceName -> MemberName -> Signal
D.signal ([Char] -> ObjectPath
D.objectPath_ ([Char] -> ObjectPath) -> [Char] -> ObjectPath
forall a b. (a -> b) -> a -> b
$ [Char]
pathPrefix[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"/"[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
p) InterfaceName
interface MemberName
member) {
    signalBody :: [Variant]
D.signalBody = [[Char] -> Variant
forall a. IsVariant a => a -> Variant
D.toVariant [Char]
s]
    }