diff options
| author | Michael Albinus | 2008-07-31 19:25:00 +0000 |
|---|---|---|
| committer | Michael Albinus | 2008-07-31 19:25:00 +0000 |
| commit | 98c38bfc5658e4d7190217f0afbd03b7d5a60663 (patch) | |
| tree | fb148bc87d4da1784a2f0c3cc0250b59d4bf59d6 | |
| parent | 13ecc6dc5310a953887b5c22cb51b3ff6f716da7 (diff) | |
| download | emacs-98c38bfc5658e4d7190217f0afbd03b7d5a60663.tar.gz emacs-98c38bfc5658e4d7190217f0afbd03b7d5a60663.zip | |
* 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.
| -rw-r--r-- | lisp/net/dbus.el | 165 |
1 files changed, 124 insertions, 41 deletions
diff --git a/lisp/net/dbus.el b/lisp/net/dbus.el index 2b1f4534aae..3cba1c3a630 100644 --- a/lisp/net/dbus.el +++ b/lisp/net/dbus.el | |||
| @@ -62,6 +62,21 @@ | |||
| 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." |
| @@ -70,7 +85,7 @@ Otherwise, return result of last form in BODY, or all other errors." | |||
| 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 | ||
| @@ -80,6 +95,13 @@ Otherwise, return result of last form in BODY, or all other errors." | |||
| 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)) |
| 82 | 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'.") | ||
| 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). |
| @@ -120,6 +142,42 @@ been unregistered, `nil' otherwise." | |||
| 120 | (setq value t))) | 142 | (setq value t))) |
| 121 | value)) | 143 | value)) |
| 122 | 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)))) | ||
| 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 |
| @@ -166,7 +224,7 @@ usage: (dbus-name-owner-changed-handler service old-owner new-owner)" | |||
| 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) |
| @@ -181,17 +239,18 @@ usage: (dbus-name-owner-changed-handler service old-owner new-owner)" | |||
| 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." |
| @@ -200,37 +259,54 @@ not well formed." | |||
| 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. |
| @@ -241,15 +317,22 @@ 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. |
| @@ -257,7 +340,7 @@ 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. |
| @@ -265,7 +348,7 @@ 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. |
| @@ -273,7 +356,7 @@ 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. |
| @@ -282,7 +365,7 @@ 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. |
| @@ -641,8 +724,8 @@ returned." | |||
| 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 |