Mercurial > emacs
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. |