+ (connection++)
+ (clean null? (map message-header HDRS))))
+ BODY ))
+
+;; (:invoke OBJ METHOD ARGS FLAGS)
+; Perform a METHOD_CALL on the (self) object
+;; The given METHOD has format "INTERFACE.NAME(SIGNATURE)" with the
+;; "INTERFACE." bit optional. The function returns the list of headers
+;; of the reply message extended with reply value as a faked header
+;; named "".
+;;
+;; This function calls send-recv-message which also polls for signals
+;; until a reply is given, but any such signals are stocked up as
+;; pending for later processing on demand.
+(define (invoke METHOD ARGS (FLAGS 0))
+ (when (regex "((.+)\\.)?([^(]+)\\((.*)\\)$" METHOD 0)
+ (let ((INTERFACE $2) (MEMBER $3) (SIGNATURE $4))
+ ;;(println (list 'invoke (bus-name) INTERFACE MEMBER SIGNATURE))
+ (if (message 'METHOD_CALL FLAGS
+ (list nil ; (if SELF-NAME (list 'SENDER SELF-NAME))
+ (list 'DESTINATION (bus-name))
+ (list 'PATH (%path))
+ (if (empty? INTERFACE) nil
+ (list 'INTERFACE INTERFACE))
+ (list 'MEMBER MEMBER)
+ (if (empty? SIGNATURE) nil
+ (list 'SIGNATURE SIGNATURE))
+ )
+ (if (empty? SIGNATURE) ""
+ (pack-data SIGNATURE ARGS)))
+ (send-recv-message $it)
+ nil
+ ))))
+
+;; Context variables and framework registration
+
+(setf
+ SYSTEM-BUS (MAIN:DbusConnection "/run/dbus/system_bus_socket")
+ APPID (:initialize SYSTEM-BUS)
+ ROOT (Dbus "/org/freedesktop/DBus")
+ APPNAME (if (lookup "" (:invoke ROOT "org.freedesktop.DBus.Hello()"))
+ ($it 0))
+ )
+
+;; Installation of some framework notification handlers
+
+;; Helper method to notify
+(define (signal-trace ARGS)
+ (die nil "** Got:" KEY ARGS ))
+
+(:handler ROOT "org.freedesktop.DBus.NameAcquired(s)" signal-trace)
+(:handler ROOT "org.freedesktop.DBus.NameLost(s)" signal-trace)
+(:handler ROOT "org.freedesktop.DBus.NameOwnerChanged(sss)" signal-trace)
+
+ ; Process notifications that came with the registration handshake
+(process-all-pending)
+
+;; Set up the Dbus event loop as prompt-event handler
+(prompt-event Dbus:main-loop)
+
+;;######################################################################
+;;
+;; Some tidbits
+
+;;org.freedesktop.DBus.Peer.Ping ()
+;;org.freedesktop.DBus.Peer.GetMachineId (out STRING machine_uuid)
+;;org.freedesktop.DBus.Introspectable.Introspect (out STRING xml_data)
+;;org.freedesktop.DBus.Properties.Get (
+;; in STRING interface_name,
+;; in STRING property_name,
+;; out VARIANT value);
+;;org.freedesktop.DBus.Properties.Set (
+;; in STRING interface_name,
+;; in STRING property_name,
+;; in VARIANT value);
+;;org.freedesktop.DBus.Properties.GetAll (
+;; in STRING interface_name,
+;; out ARRAY of DICT_ENTRY<STRING,VARIANT> props);
+;;org.freedesktop.DBus.Properties.PropertiesChanged (
+;; STRING interface_name,
+;; ARRAY of DICT_ENTRY<STRING,VARIANT> changed_properties,
+;; ARRAY<STRING> invalidated_properties);
+;;org.freedesktop.DBus.ObjectManager.GetManagedObjects (
+;; out ARRAY of
+;; DICT_ENTRY<OBJPATH,ARRAY of
+;; DICT_ENTRY<STRING,ARRAY of
+;; DICT_ENTRY<STRING,VARIANT>>>
+;; objpath_interfaces_and_properties);
+;;;;
+;;org.freedesktop.DBus.Hello():s
+;;org.freedesktop.DBus.RequestName(su):u
+;;org.freedesktop.DBus.ReleaseName(s):u
+;;org.freedesktop.DBus.ListQueuedOwners (s):as
+;;org.freedesktop.DBus.ListNames():as
+;;org.freedesktop.DBus.ListActivatableNames():as
+;;org.freedesktop.DBus.NameHasOwner(s):b
+;;org.freedesktop.DBus.NameOwnerChanged(sss) -- signal
+;;org.freedesktop.DBus.NameLost(s) -- signal
+;;org.freedesktop.DBus.NameAcquired(s) -- signal
+;;org.freedesktop.DBus.ActivatableServicesChanged() -- signal
+;;org.freedesktop.DBus.StartServiceByName(s,u):u
+;;org.freedesktop.DBus.UpdateActivationEnvironment(a(ss)):?
+;;org.freedesktop.DBus.GetNameOwner(s):s
+;;org.freedesktop.DBus.GetConnectionUnixUser(s):u
+;;org.freedesktop.DBus.GetConnectionUnixProcessID(s):u
+;;org.freedesktop.DBus.GetConnectionCredentials(s):a(sv)
+;;org.freedesktop.DBus.GetAdtAuditSessionData(s):ay
+;;org.freedesktop.DBus.GetConnectionSELinuxSecurityContext(s):ay
+;;org.freedesktop.DBus.AddMatch(s):? (org.freedesktop.DBus.Error.OOM)
+;;org.freedesktop.DBus.RemoveMatch(s):?
+;;org.freedesktop.DBus.GetId():s
+;;org.freedesktop.DBus.Monitoring.BecomeMonitor(asu):?
+
+;;org.freedesktop.DBus.AddMatch(s)
+;eg
+;"type='signal',sender='org.example.App2',path_namespace='/org/example/App2'"
+
+;;org.freedesktop.DBus.StartServiceByName(?)
+;;org.freedesktop.DBus.NameOwnerChanged(?)