emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 4155ca2: Document D-Bus monitoring


From: Michael Albinus
Subject: master 4155ca2: Document D-Bus monitoring
Date: Sun, 27 Sep 2020 12:59:11 -0400 (EDT)

branch: master
commit 4155ca273ade47bc7e19fe4af1f41c4e764a59ba
Author: Michael Albinus <michael.albinus@gmx.de>
Commit: Michael Albinus <michael.albinus@gmx.de>

    Document D-Bus monitoring
    
    * doc/misc/dbus.texi: Replace "symbol" by "keyword" where appropriate.
    (Alternative Buses): Adapt dbus-init-bus description.
    (Errors and Events): Adapt dbus-event structure.  New defuns
    dbus-event-destination-name, dbus-event-handler and dbus-event-arguments.
    (Monitoring Events): New node.
    
    * lisp/net/dbus.el: Replace "symbol" by "keyword" where appropriate.
    (cl-lib): Require.
    (dbus-register-monitor): Adapt the argument list.
    (dbus-monitor-handler): Extend.
    (dbus-init-bus): Adapt docstring.
    
    * test/lisp/net/dbus-tests.el (dbus-test01-compound-types):
    Skip if needed.  Extend test.
---
 doc/misc/dbus.texi          | 165 +++++++++++++++++++++++---------
 lisp/net/dbus.el            | 224 ++++++++++++++++++++++++--------------------
 test/lisp/net/dbus-tests.el |   9 ++
 3 files changed, 250 insertions(+), 148 deletions(-)

diff --git a/doc/misc/dbus.texi b/doc/misc/dbus.texi
index 95d6523..4b2eab4 100644
--- a/doc/misc/dbus.texi
+++ b/doc/misc/dbus.texi
@@ -63,6 +63,7 @@ another.  An overview of D-Bus can be found at
 * Signals::                     Sending and receiving signals.
 * Alternative Buses::           Alternative buses and environments.
 * Errors and Events::           Errors and events.
+* Monitoring Events::           Monitoring events.
 * Index::                       Index including concepts, functions, variables.
 
 * GNU Free Documentation License:: The license for this documentation.
@@ -162,12 +163,13 @@ registered names.  Internally they use the basic interface
 
 @defun dbus-list-activatable-names &optional bus
 This function returns the D-Bus service names, which can be activated
-for @var{bus}.  It must be either the symbol @code{:system} (the
-default) or the symbol @code{:session}.  An activatable service is
+for @var{bus}.  It must be either the keyword @code{:system} (the
+default) or the keyword @code{:session}.  An activatable service is
 described in a service registration file.  Under GNU/Linux, such files
 are located at @file{/usr/share/dbus-1/system-services/} (for the
 @code{:system} bus) or @file{/usr/share/dbus-1/services/}.  An
-activatable service is not necessarily registered at @var{bus} already.
+activatable service is not necessarily registered at @var{bus}
+already.
 
 The result is a list of strings, which is @code{nil} when there are no
 activatable service names at all.  Example:
@@ -186,7 +188,7 @@ there are no registered service names at all.  Well known 
names are
 strings like @samp{org.freedesktop.DBus}.  Names starting with
 @samp{:} are unique names for services.
 
-@var{bus} must be either the symbol @code{:system} or the symbol
+@var{bus} must be either the keyword @code{:system} or the keyword
 @code{:session}.
 @end defun
 
@@ -196,7 +198,7 @@ known name in @var{bus}.  A service has a known name if it 
doesn't
 start with @samp{:}.  The result is a list of strings, which is
 @code{nil} when there are no known names at all.
 
-@var{bus} must be either the symbol @code{:system} or the symbol
+@var{bus} must be either the keyword @code{:system} or the keyword
 @code{:session}.
 @end defun
 
@@ -206,7 +208,7 @@ For a given service, registered at D-Bus @var{bus} under 
the name
 result is a list of strings, or @code{nil} when there are no queued
 names for @var{service} at all.
 
-@var{bus} must be either the symbol @code{:system} or the symbol
+@var{bus} must be either the keyword @code{:system} or the keyword
 @code{:session}.  @var{service} must be a known service name as
 string.
 @end defun
@@ -217,7 +219,7 @@ For a given service, registered at D-Bus @var{bus} under 
the name
 owner.  The result is a string, or @code{nil} when there is no name
 owner of @var{service}.
 
-@var{bus} must be either the symbol @code{:system} or the symbol
+@var{bus} must be either the keyword @code{:system} or the keyword
 @code{:session}.  @var{service} must be a known service name as
 string.
 @end defun
@@ -228,7 +230,7 @@ registered at D-Bus @var{bus}.  If @var{service} has not 
yet started,
 it is autostarted if possible.  The result is either @code{t} or
 @code{nil}.
 
-@var{bus} must be either the symbol @code{:system} or the symbol
+@var{bus} must be either the keyword @code{:system} or the keyword
 @code{:session}.  @var{service} must be a string.  @var{timeout}, a
 nonnegative integer, specifies the maximum number of milliseconds
 before @code{dbus-ping} must return.  The default value is 25,000.
@@ -256,7 +258,7 @@ it, you can instead write:
 This function returns the unique name, under which Emacs is registered
 at D-Bus @var{bus}, as a string.
 
-@var{bus} must be either the symbol @code{:system} or the symbol
+@var{bus} must be either the keyword @code{:system} or the keyword
 @code{:session}.
 @end defun
 
@@ -375,7 +377,7 @@ must be strings.
 This function returns all interfaces and sub-nodes of @var{service},
 registered at object path @var{path} at bus @var{bus}.
 
-@var{bus} must be either the symbol @code{:system} or the symbol
+@var{bus} must be either the keyword @code{:system} or the keyword
 @code{:session}.  @var{service} must be a known service name, and
 @var{path} must be a valid object path.  The last two parameters are
 strings.  The result, the introspection data, is a string in XML
@@ -747,8 +749,8 @@ or @var{property} cannot be read, an error is raised.  
Example:
 @defun dbus-set-property bus service path interface property [type] value
 This function sets the value of @var{property} of @var{interface} to
 @var{value}.  It will be checked at @var{bus}, @var{service},
-@var{path}.  @var{value} can be preceded by a @var{type} symbol.  When
-the value is successfully set, this function returns @var{value}.
+@var{path}.  @var{value} can be preceded by a @var{type} keyword.
+When the value is successfully set, this function returns @var{value}.
 Example:
 
 @lisp
@@ -999,8 +1001,8 @@ Other Lisp objects, like symbols or hash tables, are not 
accepted as
 input parameters.
 
 If it is necessary to use another D-Bus type, a corresponding type
-symbol can be prepended to the corresponding Lisp object.  Basic D-Bus
-types are represented by the type symbols @code{:byte},
+keyword can be prepended to the corresponding Lisp object.  Basic
+D-Bus types are represented by the type keywords @code{:byte},
 @code{:boolean}, @code{:int16}, @code{:uint16}, @code{:int32},
 @code{:uint32}, @code{:int64}, @code{:uint64}, @code{:double},
 @code{:string}, @code{:object-path}, @code{:signature} and
@@ -1040,7 +1042,7 @@ If typed explicitly, a non-@code{nil} boolean value like
 @code{:boolean 'symbol} is handled like @code{t} or @code{:boolean t}.
 
 A D-Bus compound type is always represented as a list.  The @sc{car}
-of this list can be the type symbol @code{:array}, @code{:variant},
+of this list can be the type keyword @code{:array}, @code{:variant},
 @code{:struct} or @code{:dict-entry}, which would result in a
 corresponding D-Bus container.  @code{:array} is optional, because
 this is the default compound D-Bus type for a list.
@@ -1215,7 +1217,7 @@ parameters from the object.
 @defun dbus-call-method bus service path interface method &optional :timeout 
timeout &rest args
 @anchor{dbus-call-method}
 This function calls @var{method} on the D-Bus @var{bus}.  @var{bus} is
-either the symbol @code{:system} or the symbol @code{:session}.
+either the keyword @code{:system} or the keyword @code{:session}.
 
 @var{service} is the D-Bus service name to be used.  @var{path} is the
 D-Bus object path, @var{service} is registered at.  @var{interface} is
@@ -1308,8 +1310,8 @@ emulate the @code{lshal} command on GNU/Linux systems:
 
 @defun dbus-call-method-asynchronously bus service path interface method 
handler &optional :timeout timeout &rest args
 This function calls @var{method} on the D-Bus @var{bus}
-asynchronously.  @var{bus} is either the symbol @code{:system} or the
-symbol @code{:session}.
+asynchronously.  @var{bus} is either the keyword @code{:system} or the
+keyword @code{:session}.
 
 @var{service} is the D-Bus service name to be used.  @var{path} is the
 D-Bus object path, @var{service} is registered at.  @var{interface} is
@@ -1369,7 +1371,7 @@ the following functions:
 This function registers the known name @var{service} on D-Bus
 @var{bus}.
 
-@var{bus} is either the symbol @code{:system} or the symbol
+@var{bus} is either the keyword @code{:system} or the keyword
 @code{:session}.
 
 @var{service} is the service name to be registered on the D-Bus.  It
@@ -1405,7 +1407,7 @@ We already are the primary owner.
 This function unregisters all objects from D-Bus @var{bus}, that were
 registered by Emacs for @var{service}.
 
-@var{bus} is either the symbol @code{:system} or the symbol
+@var{bus} is either the keyword @code{:system} or the keyword
 @code{:session}.
 
 @var{service} is the D-Bus service name of the D-Bus.  It must be a
@@ -1452,7 +1454,7 @@ The interface namespace @code{org.gnu.Emacs} used by 
Emacs.
 With this function, an application registers @var{method} on the D-Bus
 @var{bus}.
 
-@var{bus} is either the symbol @code{:system} or the symbol
+@var{bus} is either the keyword @code{:system} or the keyword
 @code{:session}.
 
 @var{service} is the D-Bus service name of the D-Bus object
@@ -1477,8 +1479,8 @@ cons cell, @var{handler} can return this object directly, 
instead of
 returning a list containing the object.
 
 If @var{handler} returns a reply message with an empty argument list,
-@var{handler} must return the symbol @code{:ignore} in order
-to distinguish it from @code{nil} (the boolean false).
+@var{handler} must return the keyword @code{:ignore} in order to
+distinguish it from @code{nil} (the boolean false).
 
 If @var{handler} detects an error, it shall return the list
 @code{(:error @var{error-name} @var{error-message})}.
@@ -1580,7 +1582,7 @@ The test then runs
 With this function, an application declares a @var{property} on the D-Bus
 @var{bus}.
 
-@var{bus} is either the symbol @code{:system} or the symbol
+@var{bus} is either the keyword @code{:system} or the keyword
 @code{:session}.
 
 @var{service} is the D-Bus service name of the D-Bus.  It must be a
@@ -1593,12 +1595,12 @@ discussion of @var{dont-register-service} below).
 @var{property} is the name of the property of @var{interface}.
 
 @var{access} indicates, whether the property can be changed by other
-services via D-Bus.  It must be either the symbol @code{:read},
+services via D-Bus.  It must be either the keyword @code{:read},
 @code{:write} or @code{:readwrite}.
 
 @var{value} is the initial value of the property, it can be of any
 valid type (@xref{dbus-call-method}, for details).  @var{value} can be
-preceded by a @var{type} symbol.
+preceded by a @var{type} keyword.
 
 If @var{property} already exists on @var{path}, it will be
 overwritten.  For properties with access type @code{:read} this is the
@@ -1707,7 +1709,7 @@ This function is similar to @code{dbus-call-method}.  The 
difference
 is, that there are no returning output parameters.
 
 The function emits @var{signal} on the D-Bus @var{bus}.  @var{bus} is
-either the symbol @code{:system} or the symbol @code{:session}.  It
+either the keyword @code{:system} or the keyword @code{:session}.  It
 doesn't matter whether another object has registered for @var{signal}.
 
 Signals can be unicast or broadcast messages.  For broadcast messages,
@@ -1735,7 +1737,7 @@ arguments.  They are converted into D-Bus types as 
described in
 With this function, an application registers for a signal on the D-Bus
 @var{bus}.
 
-@var{bus} is either the symbol @code{:system} or the symbol
+@var{bus} is either the keyword @code{:system} or the keyword
 @code{:session}.
 
 @var{service} is the D-Bus service name used by the sending D-Bus
@@ -1837,18 +1839,17 @@ Until now, we have spoken about the system and the 
session buses,
 which are the default buses to be connected to.  However, it is
 possible to connect to any bus with a known address.  This is a UNIX
 domain or TCP/IP socket.  Everywhere, where a @var{bus} is mentioned
-as argument of a function (the symbol @code{:system} or the symbol
+as argument of a function (the keyword @code{:system} or the keyword
 @code{:session}), this address can be used instead.  The connection to
 this bus must be initialized first.
 
 @defun dbus-init-bus bus &optional private
 This function establishes the connection to D-Bus @var{bus}.
 
-@var{bus} can be either the symbol @code{:system} or the symbol
+@var{bus} can be either the keyword @code{:system} or the keyword
 @code{:session}, or it can be a string denoting the address of the
-corresponding bus.  For the system and session buses, this function
-is called when loading @file{dbus.el}, there is no need to call it
-again.
+corresponding bus.  For the system and session buses, this function is
+called when loading @file{dbus.el}, there is no need to call it again.
 
 The function returns the number of connections this Emacs session has
 established to the @var{bus} under the same unique name
@@ -1860,11 +1861,12 @@ established.
 
 When @var{private} is non-@code{nil}, a new connection is established
 instead of reusing an existing one.  It results in a new unique name
-at the bus.  This can be used, if it is necessary to distinguish from
-another connection used in the same Emacs process, like the one
-established by GTK+.  It should be used with care for at least the
-@code{:system} and @code{:session} buses, because other Emacs Lisp
-packages might already use this connection to those buses.
+at the @var{bus}.  This can be used, if it is necessary to distinguish
+from another connection used in the same Emacs process, like the one
+established by GTK+.  If @var{bus} is the keyword @code{:system} or
+the keyword @code{:session}, the new private connection is identified
+by the keywords @code{:system-private} or @code{:session-private},
+respectively.
 
 Example: You initialize a connection to the AT-SPI bus on your host:
 
@@ -1907,7 +1909,7 @@ is supported depends on the bus daemon configuration, 
however.
 This function sets the value of the @var{bus} environment
 @var{variable} to @var{value}.
 
-@var{bus} is either a Lisp symbol, @code{:system} or @code{:session},
+@var{bus} is either a Lisp keyword, @code{:system} or @code{:session},
 or a string denoting the bus address.  Both @var{variable} and
 @var{value} should be strings.
 
@@ -1973,23 +1975,31 @@ Events, , , elisp}.  They are retrieved only, when 
Emacs runs in
 interactive mode.  The generated event has this form:
 
 @lisp
-(dbus-event @var{bus} @var{type} @var{serial} @var{service} @var{path} 
@var{interface} @var{member} @var{handler}
-        &rest @var{args})
+(dbus-event @var{bus} @var{type} @var{serial} @var{service} @var{destination} 
@var{path} @var{interface} @var{member}
+            @var{handler} &rest @var{args})
 @end lisp
 
 @var{bus} identifies the D-Bus the message is coming from.  It is
-either the symbol @code{:system} or the symbol @code{:session}.
+either a Lisp keyword, @code{:system}, @code{:session},
+@code{:system-private} or @code{:session-private}, or a string
+denoting the bus address.
 
 @var{type} is the D-Bus message type which has caused the event.  It
 can be @code{dbus-message-type-invalid},
 @code{dbus-message-type-method-call},
 @code{dbus-message-type-method-return},
 @code{dbus-message-type-error}, or @code{dbus-message-type-signal}.
-@var{serial} is the serial number of the received D-Bus message.
+@var{serial} is the serial number of the received D-Bus message,
+unless @var{type} is equal @code{dbus-message-type-error}.
 
 @var{service} and @var{path} are the unique name and the object path
-of the D-Bus object emitting the message.  @var{interface} and
-@var{member} denote the message which has been sent.
+of the D-Bus object emitting the message.  @var{destination} is the
+D-Bus name the message is dedicated to, or @code{nil} in case the
+message is a broadcast signal.
+
+@var{interface} and @var{member} denote the message which has been
+sent.  When @var{type} is @code{dbus-message-type-error}, @var{member}
+is the error name.
 
 @var{handler} is the callback function which has been registered for
 this message (@pxref{Signals}).  @var{args} are the typed arguments as
@@ -2010,7 +2020,7 @@ callback function in order to retrieve the information 
from the event.
 
 @defun dbus-event-bus-name event
 This function returns the bus name @var{event} is coming from.  The
-result is either the symbol @code{:system} or the symbol
+result is either the keyword @code{:system} or the keyword
 @code{:session}.
 @end defun
 
@@ -2029,6 +2039,11 @@ This function returns the unique name of the D-Bus 
object @var{event}
 is coming from.
 @end defun
 
+@defun dbus-event-destination-name event
+This function returns the unique name of the D-Bus object @var{event}
+is dedicated to.
+@end defun
+
 @defun dbus-event-path-name event
 This function returns the object path of the D-Bus object @var{event}
 is coming from.
@@ -2044,6 +2059,16 @@ This function returns the member name of the D-Bus 
object @var{event}
 is coming from.  It is either a signal name or a method name.
 @end defun
 
+@defun dbus-event-handler event
+This function returns the handler the D-Bus object @var{event} is
+applied with.
+@end defun
+
+@defun dbus-event-arguments event
+This function returns the arguments the D-Bus object @var{event} is
+carrying on.
+@end defun
+
 D-Bus errors are not propagated during event handling, because it is
 usually not desired.  D-Bus errors in events can be made visible by
 setting the variable @code{dbus-debug} to non-@code{nil}.  They can
@@ -2074,6 +2099,54 @@ D-Bus applications running.  They should therefore check 
carefully,
 whether a given D-Bus error is related to them.
 
 
+@node Monitoring Events
+@chapter Monitoring events.
+@cindex monitoring
+
+@defun dbus-register-monitor bus &optional handler &key type sender 
destination path interface member
+This function registers @var{handler} for monitor events on the D-Bus
+@var{bus}.
+
+@var{bus} is either a Lisp keyword, @code{:system} or @code{:session},
+or a string denoting the bus address.
+
+@findex dbus-monitor-handler
+@var{handler} is the function to be called when a monitor event
+arrives.  It is called with the `args' slot of the monitor event,
+which are stripped off the type keywords.  If @var{handler} is
+@code{nil}, the default handler @code{dbus-monitor-handler} is
+applied.  This default handler behaves similar to the
+@command{dbus-monitor} program.
+
+The other arguments are keyword-value pairs.  @code{:type @var{type}}
+defines the message type to be monitored.  If given, it must be equal
+one of the strings @samp{method_call}, @samp{method_return},
+@samp{error} or @samp{signal}.
+
+@code{:sender @var{sender}} and @code{:destination @var{destination}}
+are D-Bus names.  They can be unique names, or well-known service
+names.
+
+@code{:path @var{path}} is the D-Bus object to be monitored.
+@code{:interface @var{interface}} is the name of an interface, and
+@code{:member @var{member}} is either a method name, a signal name, or
+an error name.
+
+The following form shows all D-Bus events on the session bus in buffer
+@samp{*D-Bus Monitor*}:
+
+@lisp
+(dbus-register-monitor :session)
+@end lisp
+
+And this form restricts the monitoring on D-Bus errors:
+
+@lisp
+(dbus-register-monitor :session nil :type "error")
+@end lisp
+@end defun
+
+
 @node Index
 @unnumbered Index
 
diff --git a/lisp/net/dbus.el b/lisp/net/dbus.el
index da47e5b..b1bea55 100644
--- a/lisp/net/dbus.el
+++ b/lisp/net/dbus.el
@@ -51,6 +51,7 @@
 (unless (boundp 'dbus-debug)
   (defvar dbus-debug nil))
 
+(require 'cl-lib)
 (require 'seq)
 (require 'subr-x)
 (require 'xml)
@@ -245,7 +246,7 @@ caught in `condition-case' by `dbus-error'.")
 (defvar dbus-return-values-table (make-hash-table :test #'equal)
   "Hash table for temporarily storing arguments of reply messages.
 A key in this hash table is a list (:serial BUS SERIAL), like in
-`dbus-registered-objects-table'.  BUS is either a Lisp symbol,
+`dbus-registered-objects-table'.  BUS is either a Lisp keyword,
 `:system' or `:session', or a string denoting the bus address.
 SERIAL is the serial number of the reply message.
 
@@ -279,8 +280,8 @@ The result will be made available in 
`dbus-return-values-table'."
 (defun dbus-call-method (bus service path interface method &rest args)
   "Call METHOD on the D-Bus BUS.
 
-BUS is either a Lisp symbol, `:system' or `:session', or a string
-denoting the bus address.
+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
@@ -301,8 +302,8 @@ converted into D-Bus types via the following rules:
   string    => DBUS_TYPE_STRING
   list      => DBUS_TYPE_ARRAY
 
-All arguments can be preceded by a type symbol.  For details about
-type symbols, see Info node `(dbus)Type Conversion'.
+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
@@ -405,8 +406,8 @@ object is returned instead of a list containing this single 
Lisp object.
  (bus service path interface method handler &rest args)
  "Call METHOD on the D-Bus BUS asynchronously.
 
-BUS is either a Lisp symbol, `:system' or `:session', or a string
-denoting the bus address.
+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
@@ -431,8 +432,8 @@ converted into D-Bus types via the following rules:
   string    => DBUS_TYPE_STRING
   list      => DBUS_TYPE_ARRAY
 
-All arguments can be preceded by a type symbol.  For details about
-type symbols, see Info node `(dbus)Type Conversion'.
+All arguments can be preceded by a type keyword.  For details
+about type keywords, see Info node `(dbus)Type Conversion'.
 
 If HANDLER is a Lisp function, the function returns a key into the
 hash table `dbus-registered-objects-table'.  The corresponding entry
@@ -472,9 +473,9 @@ Example:
 (defun dbus-send-signal (bus service path interface signal &rest args)
   "Send signal SIGNAL on the D-Bus BUS.
 
-BUS is either a Lisp symbol, `:system' or `:session', or a string
-denoting the bus address.  The signal is sent from the D-Bus object
-Emacs is registered at BUS.
+BUS is either a Lisp keyword, `:system' or `:session', or a
+string denoting the bus address.  The signal is sent from the
+D-Bus object Emacs is registered at BUS.
 
 SERVICE is the D-Bus name SIGNAL is sent to.  It can be either a known
 name or a unique name.  If SERVICE is nil, the signal is sent as
@@ -492,8 +493,8 @@ converted into D-Bus types via the following rules:
   string    => DBUS_TYPE_STRING
   list      => DBUS_TYPE_ARRAY
 
-All arguments can be preceded by a type symbol.  For details about
-type symbols, see Info node `(dbus)Type Conversion'.
+All arguments can be preceded by a type keyword.  For details
+about type keywords, see Info node `(dbus)Type Conversion'.
 
 Example:
 
@@ -586,8 +587,9 @@ hash table."
 (defun dbus-setenv (bus variable value)
   "Set the value of the BUS environment variable named VARIABLE to VALUE.
 
-BUS is either a Lisp symbol, `:system' or `:session', or a string
-denoting the bus address.  Both VARIABLE and VALUE should be strings.
+BUS is either a Lisp keyword, `:system' or `:session', or a
+string denoting the bus address.  Both VARIABLE and VALUE should
+be strings.
 
 Normally, services inherit the environment of the BUS daemon.  This
 function adds to or modifies that environment when activating services.
@@ -601,8 +603,8 @@ Some bus instances, such as `:system', may disable setting 
the environment."
 (defun dbus-register-service (bus service &rest flags)
   "Register known name SERVICE on the D-Bus BUS.
 
-BUS is either a Lisp symbol, `:system' or `:session', or a string
-denoting the bus address.
+BUS is either a Lisp keyword, `:system' or `:session', or a
+string denoting the bus address.
 
 SERVICE is the D-Bus service name that should be registered.  It must
 be a known name.
@@ -663,8 +665,9 @@ placed in the queue.
 
 (defun dbus-unregister-service (bus service)
   "Unregister all objects related to SERVICE from D-Bus BUS.
-BUS is either a Lisp symbol, `:system' or `:session', or a string
-denoting the bus address.  SERVICE must be a known service name.
+BUS is either a Lisp keyword, `:system' or `:session', or a
+string denoting the bus address.  SERVICE must be a known service
+name.
 
 The function returns a keyword, indicating the result of the
 operation.  One of the following keywords is returned:
@@ -699,8 +702,8 @@ queue of this service."
   (bus service path interface signal handler &rest args)
   "Register for a signal on the D-Bus BUS.
 
-BUS is either a Lisp symbol, `:system' or `:session', or a string
-denoting the bus address.
+BUS is either a Lisp keyword, `:system' or `:session', or a
+string denoting the bus address.
 
 SERVICE is the D-Bus service name used by the sending D-Bus object.
 It can be either a known name or the unique name of the D-Bus object
@@ -854,8 +857,8 @@ Example:
   (bus service path interface method handler &optional dont-register-service)
   "Register METHOD on the D-Bus BUS.
 
-BUS is either a Lisp symbol, `:system' or `:session', or a string
-denoting the bus address.
+BUS is either a Lisp keyword, `:system' or `:session', or a
+string denoting the bus address.
 
 SERVICE is the D-Bus service name of the D-Bus object METHOD is
 registered for.  It must be a known name (see discussion of
@@ -869,7 +872,7 @@ HANDLER is a Lisp function to be called when a method call 
is
 received.  It must accept the input arguments of METHOD.  The
 return value of HANDLER is used for composing the returning D-Bus
 message.  If HANDLER returns a reply message with an empty
-argument list, HANDLER must return the symbol `:ignore' in order
+argument list, HANDLER must return the keyword `:ignore' in order
 to distinguish it from nil (the boolean false).
 
 If HANDLER detects an error, it shall return the list `(:error
@@ -1039,7 +1042,7 @@ EVENT is a list which starts with symbol `dbus-event':
               INTERFACE MEMBER HANDLER &rest ARGS)
 
 BUS identifies the D-Bus the message is coming from.  It is
-either a Lisp symbol, `:system', `:session', `:systemp-private'
+either a Lisp keyword, `:system', `:session', `:systemp-private'
 or `:session-private', or a string denoting the bus address.
 
 TYPE is the D-Bus message type which has caused the event, SERIAL
@@ -1048,7 +1051,7 @@ equal `dbus-message-type-method-return' or 
`dbus-message-type-error'.
 
 SERVICE and PATH are the unique name and the object path of the
 D-Bus object emitting the message.  DESTINATION is the D-Bus name
-the message is dedicated to, or nil in case thje message is a
+the message is dedicated to, or nil in case the message is a
 broadcast signal.
 
 INTERFACE and MEMBER denote the message which has been sent.
@@ -1064,7 +1067,7 @@ formed."
   (when dbus-debug (message "DBus-Event %s" event))
   (unless (and (listp event)
               (eq (car event) 'dbus-event)
-              ;; Bus symbol.
+              ;; Bus keyword.
               (or (keywordp (nth 1 event))
                   (stringp (nth 1 event)))
               ;; Type.
@@ -1181,8 +1184,8 @@ If the HANDLER returns a `dbus-error', it is propagated 
as return message."
 
 (defun dbus-event-bus-name (event)
   "Return the bus name the event is coming from.
-The result is either a Lisp symbol, `:system' or `:session', or a
-string denoting the bus address.  EVENT is a D-Bus event, see
+The result is either a Lisp keyword, `:system' or `:session', or
+a string denoting the bus address.  EVENT is a D-Bus event, see
 `dbus-check-event'.  This function signals a `dbus-error' if the
 event is not well formed."
   (dbus-check-event event)
@@ -1375,11 +1378,11 @@ It will be registered for all objects created by 
`dbus-register-service'."
   "Return all interfaces and sub-nodes of SERVICE,
 registered at object path PATH at bus BUS.
 
-BUS is either a Lisp symbol, `:system' or `:session', or a string
-denoting the bus address.  SERVICE must be a known service name,
-and PATH must be a valid object path.  The last two parameters
-are strings.  The result, the introspection data, is a string in
-XML format."
+BUS is either a Lisp keyword, `:system' or `:session', or a
+string denoting the bus address.  SERVICE must be a known service
+name, and PATH must be a valid object path.  The last two
+parameters are strings.  The result, the introspection data, is a
+string in XML format."
   ;; We don't want to raise errors.
   (let (dbus-debug)
     (dbus-ignore-errors
@@ -1596,7 +1599,7 @@ valid D-Bus value, or nil if there is no PROPERTY, or 
PROPERTY cannot be read."
 (defun dbus-set-property (bus service path interface property &rest args)
   "Set value of PROPERTY of INTERFACE to VALUE.
 It will be checked at BUS, SERVICE, PATH.  VALUE can be preceded
-by a TYPE symbol.  When the value is successfully set, and the
+by a TYPE keyword.  When the value is successfully set, and the
 property's access type is not `:write', return VALUE.  Otherwise,
 return nil.
 
@@ -1651,8 +1654,8 @@ Filter out matching PATH."
     (bus service path interface property access &rest args)
   "Register PROPERTY on the D-Bus BUS.
 
-BUS is either a Lisp symbol, `:system' or `:session', or a string
-denoting the bus address.
+BUS is either a Lisp keyword, `:system' or `:session', or a
+string denoting the bus address.
 
 SERVICE is the D-Bus service name of the D-Bus.  It must be a
 known name (see discussion of DONT-REGISTER-SERVICE below).
@@ -1662,11 +1665,11 @@ discussion of DONT-REGISTER-SERVICE below).  INTERFACE 
is the
 name of the interface used at PATH, PROPERTY is the name of the
 property of INTERFACE.  ACCESS indicates, whether the property
 can be changed by other services via D-Bus.  It must be either
-the symbol `:read', `:write' or `:readwrite'.
+the keyword `:read', `:write' or `:readwrite'.
 
 VALUE is the initial value of the property, it can be of any
 valid type (see `dbus-call-method' for details).  VALUE can be
-preceded by a TYPE symbol.
+preceded by a TYPE keyword.
 
 If PROPERTY already exists on PATH, it will be overwritten.  For
 properties with access type `:read' this is the only way to
@@ -1688,7 +1691,7 @@ clients from discovering the still incomplete interface.
 
 \(dbus-register-property BUS SERVICE PATH INTERFACE PROPERTY ACCESS \
 [TYPE] VALUE &optional EMITS-SIGNAL DONT-REGISTER-SERVICE)"
-  (let (;; Read basic type symbol.
+  (let (;; Read basic type keyword.
         (type (when (keywordp (car args)) (pop args)))
         (value (pop args))
         (emits-signal (pop args))
@@ -1973,68 +1976,53 @@ It will be registered for all objects created by 
`dbus-register-service'."
         result)
        '(:signature "{oa{sa{sv}}}"))))))
 
-(defun dbus-register-monitor
-    (bus &optional service path interface member handler &rest args)
+(cl-defun dbus-register-monitor
+    (bus &optional handler &key type sender destination path interface member)
   "Register HANDLER for monitor events on the D-Bus BUS.
 
-BUS is either a Lisp symbol, `:system' or `:session', or a string
-denoting the bus address.
+BUS is either a Lisp keyword, `:system' or `:session', or a
+string denoting the bus address.
 
-SERVICE is the D-Bus service name of the D-Bus.  It must be a
-known name (see discussion of DONT-REGISTER-SERVICE below).
+HANDLER is the function to be called when a monitor event
+arrives.  It is called with the `args' slot of the monitor event,
+which are stripped off the type keywords.  If HANDLER is nil, the
+default handler `dbus-monitor-handler' is applied.
 
-PATH is the D-Bus object path SERVICE is registered at (see
-discussion of DONT-REGISTER-SERVICE below).  INTERFACE is the
-name of the interface used at PATH. MEMBER is either a method
-name, a signal name, or an error name.
+The other arguments are keyword-value pairs.  `:type TYPE'
+defines the message type to be monitored.  If given, it must be
+equal one of the strings \"method_call\", \"method_return\",
+\"error\" or \"signal\".
 
-HANDLER is the function to be called when a monitor event
-arrives.  If nil, the default handler `dbus-monitor-handler' is
-applied.  It is called with ARGS as arguments."
+`:sender SENDER' and `:destination DESTINATION' are D-Bus names.
+They can be unique names, or well-known service names.
 
+`:path PATH' is the D-Bus object to be monitored.  `:interface
+INTERFACE' is the name of an interface, and `:member MEMBER' is
+either a method name, a signal name, or an error name."
   (let ((bus-private (if (eq bus :system) :system-private
                        (if (eq bus :session) :session-private bus)))
-        keyword type rule1 rule2 key key1 value)
+        rule key key1 value)
     (unless handler (setq handler #'dbus-monitor-handler))
-    ;; Read arguments.
-    (while args
-      (when (keywordp (setq keyword (pop args)))
-        (cond
-         ((eq :type keyword)
-          ;; Must be "signal", "method_call", "method_return", or "error".
-          (setq type (pop args))))))
-    ;; Compose rules.
-    (setq rule1
-          (or
-           (string-join
-            (delq nil
-                  (list (when service (format "sender='%s'" service))
-                       (when path (format "path='%s'" path))
-                       (when interface (format "interface='%s'" interface))
-                       (when member (format "member='%s'" member))
-                       (when type (format "type='%s'" type))))
-            ",")
-           "")
-          rule2
-          (when service
-            (string-join
-             (delq nil
-                   (list (format "destination='%s'" service)
-                        (when path (format "path='%s'" path))
-                        (when interface (format "interface='%s'" interface))
-                        (when member (format "member='%s'" member))
-                        (when type (format "type='%s'" type))))
-             ",")))
+    ;; Compose rule.
+    (setq rule
+          (string-join
+           (delq nil (mapcar
+                      (lambda (item)
+                        (when (cdr item)
+                          (format "%s='%s'" (car item) (cdr item))))
+                      `(("type" . ,type) ("sender" . ,sender)
+                        ("destination" . ,destination) ("path" . ,path)
+                        ("interface" . ,interface) ("member" . ,member))))
+           ",")
+          rule (or rule ""))
 
     (unless (ignore-errors (dbus-get-unique-name bus-private))
       (dbus-init-bus bus 'private))
     (dbus-call-method
      bus-private dbus-service-dbus dbus-path-dbus dbus-interface-monitoring
-     "BecomeMonitor"
-     (append `(:array :string ,rule1) (when rule2 `(:string ,rule2)))
-     :uint32 0)
+     "BecomeMonitor" `(:array :string ,rule) :uint32 0)
 
-    (when dbus-debug (message "Matching rule \"%s\" created" rule1))
+    (when dbus-debug (message "Matching rule \"%s\" created" rule))
 
     ;; Create a hash table entry.
     (setq key (list :monitor bus-private)
@@ -2046,14 +2034,19 @@ applied.  It is called with ARGS as arguments."
     (when dbus-debug (message "%s" dbus-registered-objects-table))
 
     ;; Return the object.
-    (list key (list service path handler))))
+    (list key key1)))
 
 (defun dbus-monitor-handler (&rest _args)
   "Default handler for the \"org.freedesktop.DBus.Monitoring.BecomeMonitor\" 
interface.
-It will be applied all objects created by `dbus-register-monitor'."
+It will be applied for all objects created by
+`dbus-register-monitor' which don't declare an own handler.."
   (with-current-buffer (get-buffer-create "*D-Bus Monitor*")
     (special-mode)
+    ;; Move forward and backward between messages.
+    (local-set-key [?n] #'forward-paragraph)
+    (local-set-key [?p] #'backward-paragraph)
     (let* ((inhibit-read-only t)
+           (point (point))
            (eobp (eobp))
            (event last-input-event)
            (type (dbus-event-message-type event))
@@ -2079,7 +2072,33 @@ It will be applied all objects created by 
`dbus-register-monitor'."
           sender destination serial path interface member))
         (dolist (arg arguments)
           (pp (dbus-flatten-types arg) (current-buffer)))
-        (insert "\n"))
+        (insert "\n")
+        ;; Show byte arrays as string.
+        (goto-char point)
+        (while (re-search-forward
+                "(:array\\( :byte [[:digit:]]+\\)+)" nil 'noerror)
+          (put-text-property
+           (match-beginning 0) (match-end 0)
+           'help-echo (dbus-byte-array-to-string (read (match-string 0)))))
+        ;; Show fixed numbers.
+        (goto-char point)
+        (while (re-search-forward
+                (concat
+                 (regexp-opt
+                  '(":int16" ":uint16" ":int32" ":uint32" ":int64" ":uint64"))
+                 " \\([-+[:digit:]]+\\)")
+                nil 'noerror)
+          (put-text-property
+           (match-beginning 1) (match-end 1)
+           'help-echo
+           (format
+            "#o%o, #x%X" (read (match-string 1)) (read (match-string 1)))))
+        ;; Show floating numbers.
+        (goto-char point)
+        (while (re-search-forward ":double \\([-+.[:digit:]]+\\)" nil 'noerror)
+          (put-text-property
+           (match-beginning 1) (match-end 1)
+           'help-echo (format "%e" (read (match-string 1))))))
       (when eobp
         (goto-char (point-max))))))
 
@@ -2115,10 +2134,11 @@ pending at the time of disconnect to fail."
 (defun dbus-init-bus (bus &optional private)
   "Establish the connection to D-Bus BUS.
 
-BUS can be either the symbol `:system' or the symbol `:session', or it
-can be a string denoting the address of the corresponding bus.  For
-the system and session buses, this function is called when loading
-`dbus.el', there is no need to call it again.
+BUS can be either the keyword `:system' or the keyword
+`:session', or it can be a string denoting the address of the
+corresponding bus.  For the system and session buses, this
+function is called when loading `dbus.el', there is no need to
+call it again.
 
 The function returns the number of connections this Emacs session
 has established to the BUS under the same unique name (see
@@ -2128,13 +2148,13 @@ example, if Emacs is linked with the GTK+ toolkit, and 
it runs in
 a GTK+-aware environment like GNOME, another connection might
 already be established.
 
-When PRIVATE is non-nil, a new connection is established instead of
-reusing an existing one.  It results in a new unique name at the bus.
-This can be used, if it is necessary to distinguish from another
-connection used in the same Emacs process, like the one established by
-GTK+.  It should be used with care for at least the `:system' and
-`:session' buses, because other Emacs Lisp packages might already use
-this connection to those buses."
+When PRIVATE is non-nil, a new connection is established instead
+of reusing an existing one.  It results in a new unique name at
+the bus.  This can be used, if it is necessary to distinguish
+from another connection used in the same Emacs process, like the
+one established by GTK+.  If BUS is the keyword `:system' or the
+keyword `:session', the new connection is identified by the
+keywords `:system-private' or `:session-private', respectively."
   (or (featurep 'dbusbind)
       (signal 'dbus-error (list "Emacs not compiled with dbus support")))
   (prog1
diff --git a/test/lisp/net/dbus-tests.el b/test/lisp/net/dbus-tests.el
index 0f5582b..b853542 100644
--- a/test/lisp/net/dbus-tests.el
+++ b/test/lisp/net/dbus-tests.el
@@ -66,6 +66,7 @@
 (ert-deftest dbus-test01-type-conversion ()
   "Check type conversion functions."
   (skip-unless dbus--test-enabled-session-bus)
+
   (let ((ustr "0123abc_xyz\x01\xff")
        (mstr "Grüß Göttin"))
     (should
@@ -97,6 +98,7 @@
 (ert-deftest dbus-test01-basic-types ()
   "Check basic D-Bus type arguments."
   (skip-unless dbus--test-enabled-session-bus)
+
   ;; Unknown keyword.
   (should-error
    (dbus-check-arguments :session dbus--test-service :keyword)
@@ -288,6 +290,8 @@
 
 (ert-deftest dbus-test01-compound-types ()
   "Check basic D-Bus type arguments."
+  (skip-unless dbus--test-enabled-session-bus)
+
   ;; `:array'.  It contains several elements of the same type.
   (should (dbus-check-arguments :session dbus--test-service '("string")))
   (should (dbus-check-arguments :session dbus--test-service '(:array 
"string")))
@@ -327,6 +331,11 @@
    (dbus-check-arguments
     :session dbus--test-service
     '(:array (:dict-entry :string "string" :boolean t))))
+  ;; This is an alternative syntax.  FIXME: Shall this be supported?
+  (should
+   (dbus-check-arguments
+    :session dbus--test-service
+    '(:array :dict-entry (:string "string" :boolean t))))
   ;; The second element is `nil' (implicitly).  FIXME: Is this right?
   (should
    (dbus-check-arguments



reply via email to

[Prev in Thread] Current Thread [Next in Thread]