diff options
| author | Michael Albinus | 2008-01-21 20:06:15 +0000 |
|---|---|---|
| committer | Michael Albinus | 2008-01-21 20:06:15 +0000 |
| commit | 246a286b9b7ddfe6854cb06112f7a91b13626aa9 (patch) | |
| tree | 77e869cd2e511b3412bffa0cf2a560999c1f61e7 | |
| parent | d2e4a6c90428e7bce7ee7d71e2cc5b2ee0ee40d9 (diff) | |
| download | emacs-246a286b9b7ddfe6854cb06112f7a91b13626aa9.tar.gz emacs-246a286b9b7ddfe6854cb06112f7a91b13626aa9.zip | |
* net/dbus.el (dbus-ignore-errors): New macro.
(dbus-unregister-object): New defun. Moved from dbusbind.c.
(dbus-handle-event, dbus-list-activatable-names, dbus-list-names)
(dbus-list-queued-owners, dbus-get-name-owner, dbus-introspect)
(dbus-get-signatures): Apply `dbus-ignore-errors'.
| -rw-r--r-- | lisp/net/dbus.el | 185 |
1 files changed, 107 insertions, 78 deletions
diff --git a/lisp/net/dbus.el b/lisp/net/dbus.el index 83075762b73..ef84db1ccf7 100644 --- a/lisp/net/dbus.el +++ b/lisp/net/dbus.el | |||
| @@ -46,6 +46,17 @@ | |||
| 46 | (defconst dbus-interface-introspectable "org.freedesktop.DBus.Introspectable" | 46 | (defconst dbus-interface-introspectable "org.freedesktop.DBus.Introspectable" |
| 47 | "The interface supported by introspectable objects.") | 47 | "The interface supported by introspectable objects.") |
| 48 | 48 | ||
| 49 | (defmacro dbus-ignore-errors (&rest body) | ||
| 50 | "Execute BODY; signal D-Bus error when `dbus-debug' is non-nil. | ||
| 51 | Otherwise, return result of last form in BODY, or all other errors." | ||
| 52 | `(condition-case err | ||
| 53 | (progn ,@body) | ||
| 54 | (dbus-error (when dbus-debug (signal (car err) (cdr err)))))) | ||
| 55 | |||
| 56 | (put 'dbus-ignore-errors 'lisp-indent-function 0) | ||
| 57 | (put 'dbus-ignore-errors 'edebug-form-spec '(form symbolp body)) | ||
| 58 | (font-lock-add-keywords 'emacs-lisp-mode '("\\<dbus-ignore-errors\\>")) | ||
| 59 | |||
| 49 | 60 | ||
| 50 | ;;; Hash table of registered functions. | 61 | ;;; Hash table of registered functions. |
| 51 | 62 | ||
| @@ -64,6 +75,35 @@ hash table." | |||
| 64 | dbus-registered-functions-table) | 75 | dbus-registered-functions-table) |
| 65 | result)) | 76 | result)) |
| 66 | 77 | ||
| 78 | (defun dbus-unregister-object (object) | ||
| 79 | "Unregister OBJECT from D-Bus. | ||
| 80 | OBJECT must be the result of a preceding `dbus-register-method' | ||
| 81 | or `dbus-register-signal' call. It returns t if OBJECT has been | ||
| 82 | unregistered, nil otherwise." | ||
| 83 | ;; Check parameter. | ||
| 84 | (unless (and (consp object) (not (null (car object))) (consp (cdr object))) | ||
| 85 | (signal 'wrong-type-argument (list 'D-Bus object))) | ||
| 86 | |||
| 87 | ;; Find the corresponding entry in the hash table. | ||
| 88 | (let* ((key (car object)) | ||
| 89 | (value (gethash key dbus-registered-functions-table))) | ||
| 90 | ;; Loop over the registered functions. | ||
| 91 | (while (consp value) | ||
| 92 | ;; (car value) has the structure (UNAME SERVICE PATH HANDLER). | ||
| 93 | ;; (cdr object) has the structure ((SERVICE PATH HANDLER) ...). | ||
| 94 | (if (not (equal (cdr (car value)) (car (cdr object)))) | ||
| 95 | (setq value (cdr value)) | ||
| 96 | ;; Compute new hash value. If it is empty, remove it from | ||
| 97 | ;; hash table. | ||
| 98 | (unless | ||
| 99 | (puthash | ||
| 100 | key | ||
| 101 | (delete (car value) (gethash key dbus-registered-functions-table)) | ||
| 102 | dbus-registered-functions-table) | ||
| 103 | (remhash key dbus-registered-functions-table)) | ||
| 104 | (setq value t))) | ||
| 105 | value)) | ||
| 106 | |||
| 67 | (defun dbus-name-owner-changed-handler (&rest args) | 107 | (defun dbus-name-owner-changed-handler (&rest args) |
| 68 | "Reapplies all member registrations to D-Bus. | 108 | "Reapplies all member registrations to D-Bus. |
| 69 | This handler is applied when a \"NameOwnerChanged\" signal has | 109 | This handler is applied when a \"NameOwnerChanged\" signal has |
| @@ -110,15 +150,13 @@ usage: (dbus-name-owner-changed-handler service old-owner new-owner)" | |||
| 110 | args)))))) | 150 | args)))))) |
| 111 | 151 | ||
| 112 | ;; Register the handler. | 152 | ;; Register the handler. |
| 113 | (condition-case nil | 153 | (dbus-ignore-errors |
| 114 | (progn | 154 | (dbus-register-signal |
| 115 | (dbus-register-signal | 155 | :system dbus-service-dbus dbus-path-dbus dbus-interface-dbus |
| 116 | :system dbus-service-dbus dbus-path-dbus dbus-interface-dbus | 156 | "NameOwnerChanged" 'dbus-name-owner-changed-handler) |
| 117 | "NameOwnerChanged" 'dbus-name-owner-changed-handler) | 157 | (dbus-register-signal |
| 118 | (dbus-register-signal | 158 | :session dbus-service-dbus dbus-path-dbus dbus-interface-dbus |
| 119 | :session dbus-service-dbus dbus-path-dbus dbus-interface-dbus | 159 | "NameOwnerChanged" 'dbus-name-owner-changed-handler)) |
| 120 | "NameOwnerChanged" 'dbus-name-owner-changed-handler)) | ||
| 121 | (dbus-error)) | ||
| 122 | 160 | ||
| 123 | 161 | ||
| 124 | ;;; D-Bus events. | 162 | ;;; D-Bus events. |
| @@ -168,16 +206,15 @@ part of the event, is called with arguments ARGS." | |||
| 168 | (interactive "e") | 206 | (interactive "e") |
| 169 | ;; We don't want to raise an error, because this function is called | 207 | ;; We don't want to raise an error, because this function is called |
| 170 | ;; in the event handling loop. | 208 | ;; in the event handling loop. |
| 171 | (condition-case err | 209 | (dbus-ignore-errors |
| 172 | (let (result) | 210 | (let (result) |
| 173 | (dbus-check-event event) | 211 | (dbus-check-event event) |
| 174 | (setq result (apply (nth 7 event) (nthcdr 8 event))) | 212 | (setq result (apply (nth 7 event) (nthcdr 8 event))) |
| 175 | (unless (consp result) (setq result (cons result nil))) | 213 | (unless (consp result) (setq result (cons result nil))) |
| 176 | ;; Return a message when serial is not nil. | 214 | ;; Return a message when serial is not nil. |
| 177 | (when (not (null (nth 2 event))) | 215 | (when (not (null (nth 2 event))) |
| 178 | (apply 'dbus-method-return | 216 | (apply 'dbus-method-return-internal |
| 179 | (nth 1 event) (nth 2 event) (nth 3 event) result))) | 217 | (nth 1 event) (nth 2 event) (nth 3 event) result))))) |
| 180 | (dbus-error (when dbus-debug (signal (car err) (cdr err)))))) | ||
| 181 | 218 | ||
| 182 | (defun dbus-event-bus-name (event) | 219 | (defun dbus-event-bus-name (event) |
| 183 | "Return the bus name the event is coming from. | 220 | "Return the bus name the event is coming from. |
| @@ -238,11 +275,10 @@ well formed." | |||
| 238 | "Return the D-Bus service names which can be activated as list. | 275 | "Return the D-Bus service names which can be activated as list. |
| 239 | The result is a list of strings, which is nil when there are no | 276 | The result is a list of strings, which is nil when there are no |
| 240 | activatable service names at all." | 277 | activatable service names at all." |
| 241 | (condition-case nil | 278 | (dbus-ignore-errors |
| 242 | (dbus-call-method | 279 | (dbus-call-method |
| 243 | :system dbus-service-dbus | 280 | :system dbus-service-dbus |
| 244 | dbus-path-dbus dbus-interface-dbus "ListActivatableNames") | 281 | dbus-path-dbus dbus-interface-dbus "ListActivatableNames"))) |
| 245 | (dbus-error))) | ||
| 246 | 282 | ||
| 247 | (defun dbus-list-names (bus) | 283 | (defun dbus-list-names (bus) |
| 248 | "Return the service names registered at D-Bus BUS. | 284 | "Return the service names registered at D-Bus BUS. |
| @@ -250,10 +286,9 @@ The result is a list of strings, which is nil when there are no | |||
| 250 | registered service names at all. Well known names are strings like | 286 | registered service names at all. Well known names are strings like |
| 251 | \"org.freedesktop.DBus\". Names starting with \":\" are unique names | 287 | \"org.freedesktop.DBus\". Names starting with \":\" are unique names |
| 252 | for services." | 288 | for services." |
| 253 | (condition-case nil | 289 | (dbus-ignore-errors |
| 254 | (dbus-call-method | 290 | (dbus-call-method |
| 255 | bus dbus-service-dbus dbus-path-dbus dbus-interface-dbus "ListNames") | 291 | bus dbus-service-dbus dbus-path-dbus dbus-interface-dbus "ListNames"))) |
| 256 | (dbus-error))) | ||
| 257 | 292 | ||
| 258 | (defun dbus-list-known-names (bus) | 293 | (defun dbus-list-known-names (bus) |
| 259 | "Retrieve all services which correspond to a known name in BUS. | 294 | "Retrieve all services which correspond to a known name in BUS. |
| @@ -267,20 +302,18 @@ A service has a known name if it doesn't start with \":\"." | |||
| 267 | "Return the unique names registered at D-Bus BUS and queued for SERVICE. | 302 | "Return the unique names registered at D-Bus BUS and queued for SERVICE. |
| 268 | The result is a list of strings, or nil when there are no queued name | 303 | The result is a list of strings, or nil when there are no queued name |
| 269 | owners service names at all." | 304 | owners service names at all." |
| 270 | (condition-case nil | 305 | (dbus-ignore-errors |
| 271 | (dbus-call-method | 306 | (dbus-call-method |
| 272 | bus dbus-service-dbus dbus-path-dbus | 307 | bus dbus-service-dbus dbus-path-dbus |
| 273 | dbus-interface-dbus "ListQueuedOwners" service) | 308 | dbus-interface-dbus "ListQueuedOwners" service))) |
| 274 | (dbus-error))) | ||
| 275 | 309 | ||
| 276 | (defun dbus-get-name-owner (bus service) | 310 | (defun dbus-get-name-owner (bus service) |
| 277 | "Return the name owner of SERVICE registered at D-Bus BUS. | 311 | "Return the name owner of SERVICE registered at D-Bus BUS. |
| 278 | The result is either a string, or nil if there is no name owner." | 312 | The result is either a string, or nil if there is no name owner." |
| 279 | (condition-case nil | 313 | (dbus-ignore-errors |
| 280 | (dbus-call-method | 314 | (dbus-call-method |
| 281 | bus dbus-service-dbus dbus-path-dbus | 315 | bus dbus-service-dbus dbus-path-dbus |
| 282 | dbus-interface-dbus "GetNameOwner" service) | 316 | dbus-interface-dbus "GetNameOwner" service))) |
| 283 | (dbus-error))) | ||
| 284 | 317 | ||
| 285 | (defun dbus-introspect (bus service path) | 318 | (defun dbus-introspect (bus service path) |
| 286 | "Return the introspection data of SERVICE in D-Bus BUS at object path PATH. | 319 | "Return the introspection data of SERVICE in D-Bus BUS at object path PATH. |
| @@ -291,10 +324,9 @@ Example: | |||
| 291 | \(dbus-introspect | 324 | \(dbus-introspect |
| 292 | :system \"org.freedesktop.Hal\" | 325 | :system \"org.freedesktop.Hal\" |
| 293 | \"/org/freedesktop/Hal/devices/computer\")" | 326 | \"/org/freedesktop/Hal/devices/computer\")" |
| 294 | (condition-case nil | 327 | (dbus-ignore-errors |
| 295 | (dbus-call-method | 328 | (dbus-call-method |
| 296 | bus service path dbus-interface-introspectable "Introspect") | 329 | bus service path dbus-interface-introspectable "Introspect"))) |
| 297 | (dbus-error))) | ||
| 298 | 330 | ||
| 299 | (if nil ;; Must be reworked. Shall we offer D-Bus signatures at all? | 331 | (if nil ;; Must be reworked. Shall we offer D-Bus signatures at all? |
| 300 | (defun dbus-get-signatures (bus interface signal) | 332 | (defun dbus-get-signatures (bus interface signal) |
| @@ -310,42 +342,39 @@ the third parameter is of type array of integer. | |||
| 310 | If INTERFACE or SIGNAL do not exist, or if they do not support | 342 | If INTERFACE or SIGNAL do not exist, or if they do not support |
| 311 | the D-Bus method org.freedesktop.DBus.Introspectable.Introspect, | 343 | the D-Bus method org.freedesktop.DBus.Introspectable.Introspect, |
| 312 | the function returns nil." | 344 | the function returns nil." |
| 313 | (condition-case nil | 345 | (dbus-ignore-errors |
| 314 | (let ((introspect-xml | 346 | (let ((introspect-xml |
| 315 | (with-temp-buffer | 347 | (with-temp-buffer |
| 316 | (insert (dbus-introspect bus interface)) | 348 | (insert (dbus-introspect bus interface)) |
| 317 | (xml-parse-region (point-min) (point-max)))) | 349 | (xml-parse-region (point-min) (point-max)))) |
| 318 | node interfaces signals args result) | 350 | node interfaces signals args result) |
| 319 | ;; Get the root node. | 351 | ;; Get the root node. |
| 320 | (setq node (xml-node-name introspect-xml)) | 352 | (setq node (xml-node-name introspect-xml)) |
| 321 | ;; Get all interfaces. | 353 | ;; Get all interfaces. |
| 322 | (setq interfaces (xml-get-children node 'interface)) | 354 | (setq interfaces (xml-get-children node 'interface)) |
| 323 | (while interfaces | 355 | (while interfaces |
| 324 | (when (string-equal (xml-get-attribute (car interfaces) 'name) | 356 | (when (string-equal (xml-get-attribute (car interfaces) 'name) |
| 325 | interface) | 357 | interface) |
| 326 | ;; That's the requested interface. Check for signals. | 358 | ;; That's the requested interface. Check for signals. |
| 327 | (setq signals (xml-get-children (car interfaces) 'signal)) | 359 | (setq signals (xml-get-children (car interfaces) 'signal)) |
| 328 | (while signals | 360 | (while signals |
| 329 | (when (string-equal (xml-get-attribute (car signals) 'name) | 361 | (when (string-equal (xml-get-attribute (car signals) 'name) signal) |
| 330 | signal) | 362 | ;; The signal we are looking for. |
| 331 | ;; The signal we are looking for. | 363 | (setq args (xml-get-children (car signals) 'arg)) |
| 332 | (setq args (xml-get-children (car signals) 'arg)) | 364 | (while args |
| 333 | (while args | 365 | (unless (xml-get-attribute (car args) 'type) |
| 334 | (unless (xml-get-attribute (car args) 'type) | 366 | ;; This shouldn't happen, let's escape. |
| 335 | ;; This shouldn't happen, let's escape. | 367 | (signal 'dbus-error nil)) |
| 336 | (signal 'dbus-error "")) | 368 | ;; We append the signature. |
| 337 | ;; We append the signature. | 369 | (setq |
| 338 | (setq | 370 | result (append result |
| 339 | result (append result | 371 | (list (xml-get-attribute (car args) 'type)))) |
| 340 | (list (xml-get-attribute (car args) 'type)))) | 372 | (setq args (cdr args))) |
| 341 | (setq args (cdr args))) | 373 | (setq signals nil)) |
| 342 | (setq signals nil)) | 374 | (setq signals (cdr signals))) |
| 343 | (setq signals (cdr signals))) | 375 | (setq interfaces nil)) |
| 344 | (setq interfaces nil)) | 376 | (setq interfaces (cdr interfaces))) |
| 345 | (setq interfaces (cdr interfaces))) | 377 | result))) |
| 346 | result) | ||
| 347 | ;; We ignore `dbus-error'. There might be no introspectable interface. | ||
| 348 | (dbus-error nil))) | ||
| 349 | ) ;; (if nil ... | 378 | ) ;; (if nil ... |
| 350 | 379 | ||
| 351 | (provide 'dbus) | 380 | (provide 'dbus) |