Function: dbus-call-method

dbus-call-method is a byte-compiled function defined in dbus.el.gz.

Signature

(dbus-call-method BUS SERVICE PATH INTERFACE METHOD &rest ARGS)

Documentation

Call METHOD on the D-Bus BUS.

BUS is either a Lisp keyword, :system or :session, or a string denoting the bus address.

SERVICE is the D-Bus service name to be used. PATH is the D-Bus object path SERVICE is registered at. INTERFACE is an interface offered by SERVICE. It must provide METHOD.

If the parameter :timeout is given, the following integer TIMEOUT specifies the maximum number of milliseconds before the method call must return. The default value is 25,000. If the method call doesn't return in time, a D-Bus error is raised.

All other arguments ARGS are passed to METHOD as arguments. They are converted into D-Bus types via the following rules:

  t and nil => DBUS_TYPE_BOOLEAN
  number => DBUS_TYPE_UINT32
  integer => DBUS_TYPE_INT32
  float => DBUS_TYPE_DOUBLE
  string => DBUS_TYPE_STRING
  list => DBUS_TYPE_ARRAY

All arguments can be preceded by a type keyword. For details about type keywords, see Info node (dbus)Type Conversion.

dbus-call-method returns the resulting values of METHOD as a list of Lisp objects. The type conversion happens the other direction as for input arguments. It follows the mapping rules:

  DBUS_TYPE_BOOLEAN => t or nil
  DBUS_TYPE_BYTE => natural number
  DBUS_TYPE_UINT16 => natural number
  DBUS_TYPE_INT16 => integer
  DBUS_TYPE_UINT32 => natural number
  DBUS_TYPE_UNIX_FD => natural number
  DBUS_TYPE_INT32 => integer
  DBUS_TYPE_UINT64 => natural number
  DBUS_TYPE_INT64 => integer
  DBUS_TYPE_DOUBLE => float
  DBUS_TYPE_STRING => string
  DBUS_TYPE_OBJECT_PATH => string
  DBUS_TYPE_SIGNATURE => string
  DBUS_TYPE_ARRAY => list
  DBUS_TYPE_VARIANT => list
  DBUS_TYPE_STRUCT => list
  DBUS_TYPE_DICT_ENTRY => list

Example:

(dbus-call-method
 :session "org.gnome.seahorse" "/org/gnome/seahorse/keys/openpgp"
 "org.gnome.seahorse.Keys" "GetKeyField"
 "openpgp:657984B8C7A966DD" "simple-name")

  => (t ("Philip R. Zimmermann"))

If the result of the METHOD call is just one value, the converted Lisp object is returned instead of a list containing this single Lisp object.

(dbus-call-method
 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer"
 "org.freedesktop.Hal.Device" "GetPropertyString"
 "system.kernel.machine")

  => "i686"

Probably introduced at or before Emacs version 24.3.

Source Code

;; Defined in /usr/src/emacs/lisp/net/dbus.el.gz
(defun dbus-call-method (bus service path interface method &rest args)
  "Call METHOD on the D-Bus BUS.

BUS is either a Lisp keyword, `:system' or `:session', or a
string denoting the bus address.

SERVICE is the D-Bus service name to be used.  PATH is the D-Bus
object path SERVICE is registered at.  INTERFACE is an interface
offered by SERVICE.  It must provide METHOD.

If the parameter `:timeout' is given, the following integer
TIMEOUT specifies the maximum number of milliseconds before the
method call must return.  The default value is 25,000.  If the
method call doesn't return in time, a D-Bus error is raised.

All other arguments ARGS are passed to METHOD as arguments.  They are
converted into D-Bus types via the following rules:

  t and nil => DBUS_TYPE_BOOLEAN
  number    => DBUS_TYPE_UINT32
  integer   => DBUS_TYPE_INT32
  float     => DBUS_TYPE_DOUBLE
  string    => DBUS_TYPE_STRING
  list      => DBUS_TYPE_ARRAY

All arguments can be preceded by a type keyword.  For details
about type keywords, see Info node `(dbus)Type Conversion'.

`dbus-call-method' returns the resulting values of METHOD as a list of
Lisp objects.  The type conversion happens the other direction as for
input arguments.  It follows the mapping rules:

  DBUS_TYPE_BOOLEAN     => t or nil
  DBUS_TYPE_BYTE        => natural number
  DBUS_TYPE_UINT16      => natural number
  DBUS_TYPE_INT16       => integer
  DBUS_TYPE_UINT32      => natural number
  DBUS_TYPE_UNIX_FD     => natural number
  DBUS_TYPE_INT32       => integer
  DBUS_TYPE_UINT64      => natural number
  DBUS_TYPE_INT64       => integer
  DBUS_TYPE_DOUBLE      => float
  DBUS_TYPE_STRING      => string
  DBUS_TYPE_OBJECT_PATH => string
  DBUS_TYPE_SIGNATURE   => string
  DBUS_TYPE_ARRAY       => list
  DBUS_TYPE_VARIANT     => list
  DBUS_TYPE_STRUCT      => list
  DBUS_TYPE_DICT_ENTRY  => list

Example:

\(dbus-call-method
 :session \"org.gnome.seahorse\" \"/org/gnome/seahorse/keys/openpgp\"
 \"org.gnome.seahorse.Keys\" \"GetKeyField\"
 \"openpgp:657984B8C7A966DD\" \"simple-name\")

  => (t (\"Philip R. Zimmermann\"))

If the result of the METHOD call is just one value, the converted Lisp
object is returned instead of a list containing this single Lisp object.

\(dbus-call-method
 :system \"org.freedesktop.Hal\" \"/org/freedesktop/Hal/devices/computer\"
 \"org.freedesktop.Hal.Device\" \"GetPropertyString\"
 \"system.kernel.machine\")

  => \"i686\""

  (or (featurep 'dbusbind)
      (signal 'dbus-error (list "Emacs not compiled with dbus support")))
  (or (memq bus '(:system :session :system-private :session-private))
      (stringp bus)
      (signal 'wrong-type-argument (list 'keywordp bus)))
  (or (stringp service)
      (signal 'wrong-type-argument (list 'stringp service)))
  (or (stringp path)
      (signal 'wrong-type-argument (list 'stringp path)))
  (or (stringp interface)
      (signal 'wrong-type-argument (list 'stringp interface)))
  (or (stringp method)
      (signal 'wrong-type-argument (list 'stringp method)))

  (let ((timeout (plist-get args :timeout))
        (check-interval 0.001)
	(key
	 (apply
          #'dbus-message-internal dbus-message-type-method-call
          bus service path interface method #'dbus-call-method-handler args))
        (result (cons :pending nil)))

    ;; Wait until `dbus-call-method-handler' has put the result into
    ;; `dbus-return-values-table'.  If no timeout is given, use the
    ;; default 25".  Events which are not from D-Bus must be restored.
    ;; `read-event' performs a redisplay.  This must be suppressed; it
    ;; hurts when reading D-Bus events asynchronously.

    ;; Work around bug#16775 by busy-waiting with gradual backoff for
    ;; dbus calls to complete.  A better approach would involve either
    ;; adding arbitrary wait condition support to read-event or
    ;; restructuring dbus as a kind of process object.  Poll at most
    ;; about once per second for completion.

    (puthash key result dbus-return-values-table)
    (unwind-protect
        (progn
          (with-timeout
              ((if timeout (/ timeout 1000.0) 25)
               (signal 'dbus-error `(,dbus-error-no-reply "Call timed out")))
            (while (eq (car result) :pending)
              (let ((event (let ((inhibit-redisplay t) unread-command-events)
                             (read-event nil nil check-interval))))
		(when event
		  (if (ignore-errors (dbus-check-event event))
		      (setf result (gethash key dbus-return-values-table))
		    (setf unread-command-events
			  (nconc unread-command-events
				 (cons event nil)))))
                (when (< check-interval 1)
                  (setf check-interval (* check-interval 1.05))))))
          (when (eq (car result) :error)
            (signal (cadr result) (cddr result)))
          (cdr result))
      (remhash key dbus-return-values-table))))