comparison lisp/net/dbus.el @ 97167:125ed717ddbb

* net/dbus.el (top): Don't register for "NameOwnerChanged". (dbus-message-type-invalid, dbus-message-type-method-call) (dbus-message-type-method-return, dbus-message-type-error) (dbus-message-type-signal): New defconst. (dbus-ignore-errors): Fix `edebug-form-spec' property. (dbus-return-values-table): New defvar. (dbus-call-method-non-blocking-handler, dbus-event-message-type): New defun. (dbus-check-event, dbus-handle-event, dbus-event-serial-number, ): Extend docstring. Adapt implementation according to new `dbus-event' layout. (dbus-event-service-name, dbus-event-path-name) (dbus-event-interface-name, dbus-event-member-name): Adapt implementation according to new `dbus-event' layout. (dbus-set-property): Correct `dbus-introspect-get-attribute' call.
author Michael Albinus <michael.albinus@gmx.de>
date Thu, 31 Jul 2008 19:25:00 +0000
parents 282e0881421e
children f7035abd999b
comparison
equal deleted inserted replaced
97166:23dda5132c33 97167:125ed717ddbb
60 "The interface supported by introspectable objects.") 60 "The interface supported by introspectable objects.")
61 61
62 (defconst dbus-interface-properties (concat dbus-interface-dbus ".Properties") 62 (defconst dbus-interface-properties (concat dbus-interface-dbus ".Properties")
63 "The interface for property objects.") 63 "The interface for property objects.")
64 64
65 (defconst dbus-message-type-invalid 0
66 "This value is never a valid message type.")
67
68 (defconst dbus-message-type-method-call 1
69 "Message type of a method call message.")
70
71 (defconst dbus-message-type-method-return 2
72 "Message type of a method return message.")
73
74 (defconst dbus-message-type-error 3
75 "Message type of an error reply message.")
76
77 (defconst dbus-message-type-signal 4
78 "Message type of a signal message.")
79
65 (defmacro dbus-ignore-errors (&rest body) 80 (defmacro dbus-ignore-errors (&rest body)
66 "Execute BODY; signal D-Bus error when `dbus-debug' is non-nil. 81 "Execute BODY; signal D-Bus error when `dbus-debug' is non-nil.
67 Otherwise, return result of last form in BODY, or all other errors." 82 Otherwise, return result of last form in BODY, or all other errors."
68 `(condition-case err 83 `(condition-case err
69 (progn ,@body) 84 (progn ,@body)
70 (dbus-error (when dbus-debug (signal (car err) (cdr err)))))) 85 (dbus-error (when dbus-debug (signal (car err) (cdr err))))))
71 86
72 (put 'dbus-ignore-errors 'lisp-indent-function 0) 87 (put 'dbus-ignore-errors 'lisp-indent-function 0)
73 (put 'dbus-ignore-errors 'edebug-form-spec '(form symbolp body)) 88 (put 'dbus-ignore-errors 'edebug-form-spec '(form body))
74 (font-lock-add-keywords 'emacs-lisp-mode '("\\<dbus-ignore-errors\\>")) 89 (font-lock-add-keywords 'emacs-lisp-mode '("\\<dbus-ignore-errors\\>"))
75 90
76 91
77 ;;; Hash table of registered functions. 92 ;;; Hash table of registered functions.
78 93
79 ;; We create it here. So we have a simple test in dbusbind.c, whether 94 ;; We create it here. So we have a simple test in dbusbind.c, whether
80 ;; the Lisp code has been loaded. 95 ;; the Lisp code has been loaded.
81 (setq dbus-registered-functions-table (make-hash-table :test 'equal)) 96 (setq dbus-registered-functions-table (make-hash-table :test 'equal))
97
98 (defvar dbus-return-values-table (make-hash-table :test 'equal)
99 "Hash table for temporary storing arguments of reply messages.
100 A key in this hash table is a list (BUS SERIAL). BUS is either the
101 symbol `:system' or the symbol `:session'. SERIAL is the serial number
102 of the reply message. See `dbus-call-method-non-blocking-handler' and
103 `dbus-call-method-non-blocking'.")
82 104
83 (defun dbus-list-hash-table () 105 (defun dbus-list-hash-table ()
84 "Returns all registered member registrations to D-Bus. 106 "Returns all registered member registrations to D-Bus.
85 The return value is a list, with elements of kind (KEY . VALUE). 107 The return value is a list, with elements of kind (KEY . VALUE).
86 See `dbus-registered-functions-table' for a description of the 108 See `dbus-registered-functions-table' for a description of the
117 (delete (car value) (gethash key dbus-registered-functions-table)) 139 (delete (car value) (gethash key dbus-registered-functions-table))
118 dbus-registered-functions-table) 140 dbus-registered-functions-table)
119 (remhash key dbus-registered-functions-table)) 141 (remhash key dbus-registered-functions-table))
120 (setq value t))) 142 (setq value t)))
121 value)) 143 value))
144
145 (defun dbus-call-method-non-blocking-handler (&rest args)
146 "Handler for reply messages of asynchronous D-Bus message calls.
147 It calls the function stored in `dbus-registered-functions-table'.
148 The result will be made available in `dbus-return-values-table'."
149 (puthash (list (dbus-event-bus-name last-input-event)
150 (dbus-event-serial-number last-input-event))
151 (if (= (length args) 1) (car args) args)
152 dbus-return-values-table))
153
154 (defun dbus-call-method-non-blocking
155 (bus service path interface method &rest args)
156 "Call METHOD on the D-Bus BUS, but don't block the event queue.
157 This is necessary for communicating to registered D-Bus methods,
158 which are running in the same Emacs process.
159
160 The arguments are the same as in `dbus-call-method'.
161
162 usage: (dbus-call-method-non-blocking
163 BUS SERVICE PATH INTERFACE METHOD
164 &optional :timeout TIMEOUT &rest ARGS)"
165
166 (let ((key
167 (apply
168 'dbus-call-method-asynchronously
169 bus service path interface method
170 'dbus-call-method-non-blocking-handler args)))
171 ;; Wait until `dbus-call-method-non-blocking-handler' has put the
172 ;; result into `dbus-return-values-table'.
173 (while (not (gethash key dbus-return-values-table nil))
174 (read-event nil nil 0.1))
175
176 ;; Cleanup `dbus-return-values-table'. Return the result.
177 (prog1
178 (gethash key dbus-return-values-table nil)
179 (remhash key dbus-return-values-table))))
122 180
123 (defun dbus-name-owner-changed-handler (&rest args) 181 (defun dbus-name-owner-changed-handler (&rest args)
124 "Reapplies all member registrations to D-Bus. 182 "Reapplies all member registrations to D-Bus.
125 This handler is applied when a \"NameOwnerChanged\" signal has 183 This handler is applied when a \"NameOwnerChanged\" signal has
126 arrived. SERVICE is the object name for which the name owner has 184 arrived. SERVICE is the object name for which the name owner has
164 (cons 222 (cons
165 (format "Wrong arguments of %s.NameOwnerChanged" dbus-interface-dbus) 223 (format "Wrong arguments of %s.NameOwnerChanged" dbus-interface-dbus)
166 args)))))) 224 args))))))
167 225
168 ;; Register the handler. 226 ;; Register the handler.
169 (ignore-errors 227 (when nil ;ignore-errors
170 (dbus-register-signal 228 (dbus-register-signal
171 :system dbus-service-dbus dbus-path-dbus dbus-interface-dbus 229 :system dbus-service-dbus dbus-path-dbus dbus-interface-dbus
172 "NameOwnerChanged" 'dbus-name-owner-changed-handler) 230 "NameOwnerChanged" 'dbus-name-owner-changed-handler)
173 (dbus-register-signal 231 (dbus-register-signal
174 :session dbus-service-dbus dbus-path-dbus dbus-interface-dbus 232 :session dbus-service-dbus dbus-path-dbus dbus-interface-dbus
179 237
180 (defun dbus-check-event (event) 238 (defun dbus-check-event (event)
181 "Checks whether EVENT is a well formed D-Bus event. 239 "Checks whether EVENT is a well formed D-Bus event.
182 EVENT is a list which starts with symbol `dbus-event': 240 EVENT is a list which starts with symbol `dbus-event':
183 241
184 (dbus-event BUS SERIAL SERVICE PATH INTERFACE MEMBER HANDLER &rest ARGS) 242 (dbus-event BUS TYPE SERIAL SERVICE PATH INTERFACE MEMBER HANDLER &rest ARGS)
185 243
186 BUS identifies the D-Bus the message is coming from. It is 244 BUS identifies the D-Bus the message is coming from. It is
187 either the symbol `:system' or the symbol `:session'. SERIAL is 245 either the symbol `:system' or the symbol `:session'. TYPE is
188 the serial number of the received D-Bus message if it is a method 246 the D-Bus message type which has caused the event, SERIAL is the
189 call, or `nil'. SERVICE and PATH are the unique name and the 247 serial number of the received D-Bus message. SERVICE and PATH
190 object path of the D-Bus object emitting the message. INTERFACE 248 are the unique name and the object path of the D-Bus object
191 and MEMBER denote the message which has been sent. HANDLER is 249 emitting the message. INTERFACE and MEMBER denote the message
192 the function which has been registered for this message. ARGS 250 which has been sent. HANDLER is the function which has been
193 are the arguments passed to HANDLER, when it is called during 251 registered for this message. ARGS are the arguments passed to
194 event handling in `dbus-handle-event'. 252 HANDLER, when it is called during event handling in
253 `dbus-handle-event'.
195 254
196 This function raises a `dbus-error' signal in case the event is 255 This function raises a `dbus-error' signal in case the event is
197 not well formed." 256 not well formed."
198 (when dbus-debug (message "DBus-Event %s" event)) 257 (when dbus-debug (message "DBus-Event %s" event))
199 (unless (and (listp event) 258 (unless (and (listp event)
200 (eq (car event) 'dbus-event) 259 (eq (car event) 'dbus-event)
201 ;; Bus symbol. 260 ;; Bus symbol.
202 (symbolp (nth 1 event)) 261 (symbolp (nth 1 event))
262 ;; Type.
263 (and (natnump (nth 2 event))
264 (< dbus-message-type-invalid (nth 2 event)))
203 ;; Serial. 265 ;; Serial.
204 (or (natnump (nth 2 event)) (null (nth 2 event))) 266 (natnump (nth 3 event))
205 ;; Service. 267 ;; Service.
206 (stringp (nth 3 event)) 268 (or (= dbus-message-type-method-return (nth 2 event))
269 (stringp (nth 4 event)))
207 ;; Object path. 270 ;; Object path.
208 (stringp (nth 4 event)) 271 (or (= dbus-message-type-method-return (nth 2 event))
272 (stringp (nth 5 event)))
209 ;; Interface. 273 ;; Interface.
210 (stringp (nth 5 event)) 274 (or (= dbus-message-type-method-return (nth 2 event))
275 (stringp (nth 6 event)))
211 ;; Member. 276 ;; Member.
212 (stringp (nth 6 event)) 277 (or (= dbus-message-type-method-return (nth 2 event))
278 (stringp (nth 7 event)))
213 ;; Handler. 279 ;; Handler.
214 (functionp (nth 7 event))) 280 (functionp (nth 8 event)))
215 (signal 'dbus-error (list "Not a valid D-Bus event" event)))) 281 (signal 'dbus-error (list "Not a valid D-Bus event" event))))
216 282
217 ;;;###autoload 283 ;;;###autoload
218 (defun dbus-handle-event (event) 284 (defun dbus-handle-event (event)
219 "Handle events from the D-Bus. 285 "Handle events from the D-Bus.
220 EVENT is a D-Bus event, see `dbus-check-event'. HANDLER, being 286 EVENT is a D-Bus event, see `dbus-check-event'. HANDLER, being
221 part of the event, is called with arguments ARGS." 287 part of the event, is called with arguments ARGS.
288 If the HANDLER returns an `dbus-error', it is propagated as return message."
222 (interactive "e") 289 (interactive "e")
223 ;; We don't want to raise an error, because this function is called 290 ;; By default, we don't want to raise an error, because this
224 ;; in the event handling loop. 291 ;; function is called in the event handling loop.
225 (dbus-ignore-errors 292 (condition-case err
226 (let (result) 293 (let (result)
227 (dbus-check-event event) 294 (dbus-check-event event)
228 (setq result (apply (nth 7 event) (nthcdr 8 event))) 295 (setq result (apply (nth 8 event) (nthcdr 9 event)))
229 (unless (consp result) (setq result (cons result nil))) 296 ;; Return a message when it is a message call.
230 ;; Return a message when serial is not `nil'. 297 (when (= dbus-message-type-method-call (nth 2 event))
231 (when (not (null (nth 2 event))) 298 (dbus-ignore-errors
232 (apply 'dbus-method-return-internal 299 (dbus-method-return-internal
233 (nth 1 event) (nth 2 event) (nth 3 event) result))))) 300 (nth 1 event) (nth 3 event) (nth 4 event) result))))
301 ;; Error handling.
302 (dbus-error
303 ;; Return an error message when it is a message call.
304 (when (= dbus-message-type-method-call (nth 2 event))
305 (dbus-ignore-errors
306 (dbus-method-error-internal
307 (nth 1 event) (nth 3 event) (nth 4 event) (cadr err))))
308 ;; Propagate D-Bus error in the debug case.
309 (when dbus-debug (signal (car err) (cdr err))))))
234 310
235 (defun dbus-event-bus-name (event) 311 (defun dbus-event-bus-name (event)
236 "Return the bus name the event is coming from. 312 "Return the bus name the event is coming from.
237 The result is either the symbol `:system' or the symbol `:session'. 313 The result is either the symbol `:system' or the symbol `:session'.
238 EVENT is a D-Bus event, see `dbus-check-event'. This function 314 EVENT is a D-Bus event, see `dbus-check-event'. This function
239 raises a `dbus-error' signal in case the event is not well 315 raises a `dbus-error' signal in case the event is not well
240 formed." 316 formed."
241 (dbus-check-event event) 317 (dbus-check-event event)
242 (nth 1 event)) 318 (nth 1 event))
243 319
320 (defun dbus-event-message-type (event)
321 "Return the message type of the corresponding D-Bus message.
322 The result is a number. EVENT is a D-Bus event, see
323 `dbus-check-event'. This function raises a `dbus-error' signal
324 in case the event is not well formed."
325 (dbus-check-event event)
326 (nth 2 event))
327
244 (defun dbus-event-serial-number (event) 328 (defun dbus-event-serial-number (event)
245 "Return the serial number of the corresponding D-Bus message. 329 "Return the serial number of the corresponding D-Bus message.
246 The result is a number in case the D-Bus message is a method 330 The result is a number. The serial number is needed for
247 call, or `nil' for all other mesage types. The serial number is 331 generating a reply message. EVENT is a D-Bus event, see
248 needed for generating a reply message. EVENT is a D-Bus event, 332 `dbus-check-event'. This function raises a `dbus-error' signal
249 see `dbus-check-event'. This function raises a `dbus-error' 333 in case the event is not well formed."
250 signal in case the event is not well formed."
251 (dbus-check-event event) 334 (dbus-check-event event)
252 (nth 2 event)) 335 (nth 3 event))
253 336
254 (defun dbus-event-service-name (event) 337 (defun dbus-event-service-name (event)
255 "Return the name of the D-Bus object the event is coming from. 338 "Return the name of the D-Bus object the event is coming from.
256 The result is a string. EVENT is a D-Bus event, see `dbus-check-event'. 339 The result is a string. EVENT is a D-Bus event, see `dbus-check-event'.
257 This function raises a `dbus-error' signal in case the event is 340 This function raises a `dbus-error' signal in case the event is
258 not well formed." 341 not well formed."
259 (dbus-check-event event) 342 (dbus-check-event event)
260 (nth 3 event)) 343 (nth 4 event))
261 344
262 (defun dbus-event-path-name (event) 345 (defun dbus-event-path-name (event)
263 "Return the object path of the D-Bus object the event is coming from. 346 "Return the object path of the D-Bus object the event is coming from.
264 The result is a string. EVENT is a D-Bus event, see `dbus-check-event'. 347 The result is a string. EVENT is a D-Bus event, see `dbus-check-event'.
265 This function raises a `dbus-error' signal in case the event is 348 This function raises a `dbus-error' signal in case the event is
266 not well formed." 349 not well formed."
267 (dbus-check-event event) 350 (dbus-check-event event)
268 (nth 4 event)) 351 (nth 5 event))
269 352
270 (defun dbus-event-interface-name (event) 353 (defun dbus-event-interface-name (event)
271 "Return the interface name of the D-Bus object the event is coming from. 354 "Return the interface name of the D-Bus object the event is coming from.
272 The result is a string. EVENT is a D-Bus event, see `dbus-check-event'. 355 The result is a string. EVENT is a D-Bus event, see `dbus-check-event'.
273 This function raises a `dbus-error' signal in case the event is 356 This function raises a `dbus-error' signal in case the event is
274 not well formed." 357 not well formed."
275 (dbus-check-event event) 358 (dbus-check-event event)
276 (nth 5 event)) 359 (nth 6 event))
277 360
278 (defun dbus-event-member-name (event) 361 (defun dbus-event-member-name (event)
279 "Return the member name the event is coming from. 362 "Return the member name the event is coming from.
280 It is either a signal name or a method name. The result is is a 363 It is either a signal name or a method name. The result is is a
281 string. EVENT is a D-Bus event, see `dbus-check-event'. This 364 string. EVENT is a D-Bus event, see `dbus-check-event'. This
282 function raises a `dbus-error' signal in case the event is not 365 function raises a `dbus-error' signal in case the event is not
283 well formed." 366 well formed."
284 (dbus-check-event event) 367 (dbus-check-event event)
285 (nth 6 event)) 368 (nth 7 event))
286 369
287 370
288 ;;; D-Bus registered names. 371 ;;; D-Bus registered names.
289 372
290 (defun dbus-list-activatable-names () 373 (defun dbus-list-activatable-names ()
639 bus service path "org.freedesktop.DBus.Properties")) 722 bus service path "org.freedesktop.DBus.Properties"))
640 ;; PROPERTY must be writable. 723 ;; PROPERTY must be writable.
641 (string-equal 724 (string-equal
642 "readwrite" 725 "readwrite"
643 (dbus-introspect-get-attribute 726 (dbus-introspect-get-attribute
644 bus service path interface property) 727 (dbus-get-property bus service path interface property)
645 "access")) 728 "access")))
646 ;; "Set" requires a variant. 729 ;; "Set" requires a variant.
647 (dbus-call-method 730 (dbus-call-method
648 bus service path dbus-interface-properties 731 bus service path dbus-interface-properties
649 "Set" interface property (list :variant value)) 732 "Set" interface property (list :variant value))
650 ;; Return VALUE. 733 ;; Return VALUE.