diff options
| author | Michael Albinus | 2008-07-18 20:20:03 +0000 |
|---|---|---|
| committer | Michael Albinus | 2008-07-18 20:20:03 +0000 |
| commit | f636d3cafdf3e7e7bacac174baec13d25aa9882d (patch) | |
| tree | d71e665b7a22579f24af652a0af9633313e716b6 | |
| parent | c961325a15277936974954818cf06d9bceed83cd (diff) | |
| download | emacs-f636d3cafdf3e7e7bacac174baec13d25aa9882d.tar.gz emacs-f636d3cafdf3e7e7bacac174baec13d25aa9882d.zip | |
* net/dbus.el (dbus-interface-properties): New defconst.
(dbus-introspect): Update docstring.
(dbus-introspect-xml, dbus-introspect-get-attribute)
(dbus-introspect-get-node-names, dbus-introspect-get-all-nodes)
(dbus-introspect-get-interface-names)
(dbus-introspect-get-interface, dbus-introspect-get-method-names)
(dbus-introspect-get-method, dbus-introspect-get-signal-names)
(dbus-introspect-get-signal, dbus-introspect-get-property-names)
(dbus-introspect-get-property)
(dbus-introspect-get-annotation-names)
(dbus-introspect-get-annotation)
(dbus-introspect-get-argument-names, dbus-introspect-get-argument)
(dbus-introspect-get-signature, dbus-get-property)
(dbus-set-property, dbus-get-all-properties): New defuns.
| -rw-r--r-- | lisp/net/dbus.el | 403 |
1 files changed, 336 insertions, 67 deletions
diff --git a/lisp/net/dbus.el b/lisp/net/dbus.el index 5b108a909f6..2b1f4534aae 100644 --- a/lisp/net/dbus.el +++ b/lisp/net/dbus.el | |||
| @@ -59,6 +59,9 @@ | |||
| 59 | (concat dbus-interface-dbus ".Introspectable") | 59 | (concat dbus-interface-dbus ".Introspectable") |
| 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") | ||
| 63 | "The interface for property objects.") | ||
| 64 | |||
| 62 | (defmacro dbus-ignore-errors (&rest body) | 65 | (defmacro dbus-ignore-errors (&rest body) |
| 63 | "Execute BODY; signal D-Bus error when `dbus-debug' is non-nil. | 66 | "Execute BODY; signal D-Bus error when `dbus-debug' is non-nil. |
| 64 | Otherwise, return result of last form in BODY, or all other errors." | 67 | Otherwise, return result of last form in BODY, or all other errors." |
| @@ -91,8 +94,8 @@ hash table." | |||
| 91 | (defun dbus-unregister-object (object) | 94 | (defun dbus-unregister-object (object) |
| 92 | "Unregister OBJECT from D-Bus. | 95 | "Unregister OBJECT from D-Bus. |
| 93 | OBJECT must be the result of a preceding `dbus-register-method' | 96 | OBJECT must be the result of a preceding `dbus-register-method' |
| 94 | or `dbus-register-signal' call. It returns t if OBJECT has been | 97 | or `dbus-register-signal' call. It returns `t' if OBJECT has |
| 95 | unregistered, nil otherwise." | 98 | been unregistered, `nil' otherwise." |
| 96 | ;; Check parameter. | 99 | ;; Check parameter. |
| 97 | (unless (and (consp object) (not (null (car object))) (consp (cdr object))) | 100 | (unless (and (consp object) (not (null (car object))) (consp (cdr object))) |
| 98 | (signal 'wrong-type-argument (list 'D-Bus object))) | 101 | (signal 'wrong-type-argument (list 'D-Bus object))) |
| @@ -183,7 +186,7 @@ EVENT is a list which starts with symbol `dbus-event': | |||
| 183 | BUS identifies the D-Bus the message is coming from. It is | 186 | BUS identifies the D-Bus the message is coming from. It is |
| 184 | either the symbol `:system' or the symbol `:session'. SERIAL is | 187 | either the symbol `:system' or the symbol `:session'. SERIAL is |
| 185 | the serial number of the received D-Bus message if it is a method | 188 | the serial number of the received D-Bus message if it is a method |
| 186 | call, or nil. SERVICE and PATH are the unique name and the | 189 | call, or `nil'. SERVICE and PATH are the unique name and the |
| 187 | object path of the D-Bus object emitting the message. INTERFACE | 190 | object path of the D-Bus object emitting the message. INTERFACE |
| 188 | and MEMBER denote the message which has been sent. HANDLER is | 191 | and MEMBER denote the message which has been sent. HANDLER is |
| 189 | the function which has been registered for this message. ARGS | 192 | the function which has been registered for this message. ARGS |
| @@ -224,7 +227,7 @@ part of the event, is called with arguments ARGS." | |||
| 224 | (dbus-check-event event) | 227 | (dbus-check-event event) |
| 225 | (setq result (apply (nth 7 event) (nthcdr 8 event))) | 228 | (setq result (apply (nth 7 event) (nthcdr 8 event))) |
| 226 | (unless (consp result) (setq result (cons result nil))) | 229 | (unless (consp result) (setq result (cons result nil))) |
| 227 | ;; Return a message when serial is not nil. | 230 | ;; Return a message when serial is not `nil'. |
| 228 | (when (not (null (nth 2 event))) | 231 | (when (not (null (nth 2 event))) |
| 229 | (apply 'dbus-method-return-internal | 232 | (apply 'dbus-method-return-internal |
| 230 | (nth 1 event) (nth 2 event) (nth 3 event) result))))) | 233 | (nth 1 event) (nth 2 event) (nth 3 event) result))))) |
| @@ -241,7 +244,7 @@ formed." | |||
| 241 | (defun dbus-event-serial-number (event) | 244 | (defun dbus-event-serial-number (event) |
| 242 | "Return the serial number of the corresponding D-Bus message. | 245 | "Return the serial number of the corresponding D-Bus message. |
| 243 | The result is a number in case the D-Bus message is a method | 246 | The result is a number in case the D-Bus message is a method |
| 244 | call, or nil for all other mesage types. The serial number is | 247 | call, or `nil' for all other mesage types. The serial number is |
| 245 | needed for generating a reply message. EVENT is a D-Bus event, | 248 | needed for generating a reply message. EVENT is a D-Bus event, |
| 246 | see `dbus-check-event'. This function raises a `dbus-error' | 249 | see `dbus-check-event'. This function raises a `dbus-error' |
| 247 | signal in case the event is not well formed." | 250 | signal in case the event is not well formed." |
| @@ -286,7 +289,7 @@ well formed." | |||
| 286 | 289 | ||
| 287 | (defun dbus-list-activatable-names () | 290 | (defun dbus-list-activatable-names () |
| 288 | "Return the D-Bus service names which can be activated as list. | 291 | "Return the D-Bus service names which can be activated as list. |
| 289 | The result is a list of strings, which is nil when there are no | 292 | The result is a list of strings, which is `nil' when there are no |
| 290 | activatable service names at all." | 293 | activatable service names at all." |
| 291 | (dbus-ignore-errors | 294 | (dbus-ignore-errors |
| 292 | (dbus-call-method | 295 | (dbus-call-method |
| @@ -295,10 +298,10 @@ activatable service names at all." | |||
| 295 | 298 | ||
| 296 | (defun dbus-list-names (bus) | 299 | (defun dbus-list-names (bus) |
| 297 | "Return the service names registered at D-Bus BUS. | 300 | "Return the service names registered at D-Bus BUS. |
| 298 | The result is a list of strings, which is nil when there are no | 301 | The result is a list of strings, which is `nil' when there are no |
| 299 | registered service names at all. Well known names are strings like | 302 | registered service names at all. Well known names are strings |
| 300 | \"org.freedesktop.DBus\". Names starting with \":\" are unique names | 303 | like \"org.freedesktop.DBus\". Names starting with \":\" are |
| 301 | for services." | 304 | unique names for services." |
| 302 | (dbus-ignore-errors | 305 | (dbus-ignore-errors |
| 303 | (dbus-call-method | 306 | (dbus-call-method |
| 304 | bus dbus-service-dbus dbus-path-dbus dbus-interface-dbus "ListNames"))) | 307 | bus dbus-service-dbus dbus-path-dbus dbus-interface-dbus "ListNames"))) |
| @@ -312,9 +315,9 @@ A service has a known name if it doesn't start with \":\"." | |||
| 312 | (add-to-list 'result name 'append))))) | 315 | (add-to-list 'result name 'append))))) |
| 313 | 316 | ||
| 314 | (defun dbus-list-queued-owners (bus service) | 317 | (defun dbus-list-queued-owners (bus service) |
| 315 | "Return the unique names registered at D-Bus BUS and queued for SERVICE. | 318 | "Return the unique names registered at D-Bus BUS and queued for SERVICE. |
| 316 | The result is a list of strings, or nil when there are no queued name | 319 | The result is a list of strings, or `nil' when there are no |
| 317 | owners service names at all." | 320 | queued name owners service names at all." |
| 318 | (dbus-ignore-errors | 321 | (dbus-ignore-errors |
| 319 | (dbus-call-method | 322 | (dbus-call-method |
| 320 | bus dbus-service-dbus dbus-path-dbus | 323 | bus dbus-service-dbus dbus-path-dbus |
| @@ -322,7 +325,7 @@ owners service names at all." | |||
| 322 | 325 | ||
| 323 | (defun dbus-get-name-owner (bus service) | 326 | (defun dbus-get-name-owner (bus service) |
| 324 | "Return the name owner of SERVICE registered at D-Bus BUS. | 327 | "Return the name owner of SERVICE registered at D-Bus BUS. |
| 325 | The result is either a string, or nil if there is no name owner." | 328 | The result is either a string, or `nil' if there is no name owner." |
| 326 | (dbus-ignore-errors | 329 | (dbus-ignore-errors |
| 327 | (dbus-call-method | 330 | (dbus-call-method |
| 328 | bus dbus-service-dbus dbus-path-dbus | 331 | bus dbus-service-dbus dbus-path-dbus |
| @@ -337,67 +340,333 @@ The result is either a string, or nil if there is no name owner." | |||
| 337 | (dbus-call-method bus service dbus-path-dbus dbus-interface-peer "Ping")) | 340 | (dbus-call-method bus service dbus-path-dbus dbus-interface-peer "Ping")) |
| 338 | (dbus-error nil))) | 341 | (dbus-error nil))) |
| 339 | 342 | ||
| 340 | (defun dbus-introspect (bus service path) | 343 | |
| 341 | "Return the introspection data of SERVICE in D-Bus BUS at object path PATH. | 344 | ;;; D-Bus introspection. |
| 342 | The data are in XML format. | ||
| 343 | |||
| 344 | Example: | ||
| 345 | 345 | ||
| 346 | \(dbus-introspect | 346 | (defun dbus-introspect (bus service path) |
| 347 | :system \"org.freedesktop.Hal\" | 347 | "This function returns all interfaces and sub-nodes of SERVICE, |
| 348 | \"/org/freedesktop/Hal/devices/computer\")" | 348 | registered at object path PATH at bus BUS. |
| 349 | |||
| 350 | BUS must be either the symbol `:system' or the symbol `:session'. | ||
| 351 | SERVICE must be a known service name, and PATH must be a valid | ||
| 352 | object path. The last two parameters are strings. The result, | ||
| 353 | the introspection data, is a string in XML format." | ||
| 354 | ;; We don't want to raise errors. | ||
| 349 | (dbus-ignore-errors | 355 | (dbus-ignore-errors |
| 350 | (dbus-call-method | 356 | (dbus-call-method |
| 351 | bus service path dbus-interface-introspectable "Introspect"))) | 357 | bus service path dbus-interface-introspectable "Introspect"))) |
| 352 | 358 | ||
| 353 | (if nil ;; Must be reworked. Shall we offer D-Bus signatures at all? | 359 | (defun dbus-introspect-xml (bus service path) |
| 354 | (defun dbus-get-signatures (bus interface signal) | 360 | "Return the introspection data of SERVICE in D-Bus BUS at object path PATH. |
| 355 | "Retrieve SIGNAL's type signatures from D-Bus. | 361 | The data are a parsed list. The root object is a \"node\", |
| 356 | The result is a list of SIGNAL's type signatures. Example: | 362 | representing the object path PATH. The root object can contain |
| 357 | 363 | \"interface\" and further \"node\" objects." | |
| 358 | \(\"s\" \"b\" \"ai\"\) | 364 | ;; We don't want to raise errors. |
| 365 | (xml-node-name | ||
| 366 | (ignore-errors | ||
| 367 | (with-temp-buffer | ||
| 368 | (insert (dbus-introspect bus service path)) | ||
| 369 | (xml-parse-region (point-min) (point-max)))))) | ||
| 370 | |||
| 371 | (defun dbus-introspect-get-attribute (object attribute) | ||
| 372 | "Return the ATTRIBUTE value of D-Bus introspection OBJECT. | ||
| 373 | ATTRIBUTE must be a string according to the attribute names in | ||
| 374 | the D-Bus specification." | ||
| 375 | (xml-get-attribute-or-nil object (intern attribute))) | ||
| 376 | |||
| 377 | (defun dbus-introspect-get-node-names (bus service path) | ||
| 378 | "Return all node names of SERVICE in D-Bus BUS at object path PATH. | ||
| 379 | It returns a list of strings. The node names stand for further | ||
| 380 | object paths of the D-Bus service." | ||
| 381 | (let ((object (dbus-introspect-xml bus service path)) | ||
| 382 | result) | ||
| 383 | (dolist (elt (xml-get-children object 'node) result) | ||
| 384 | (add-to-list | ||
| 385 | 'result (dbus-introspect-get-attribute elt "name") 'append)))) | ||
| 386 | |||
| 387 | (defun dbus-introspect-get-all-nodes (bus service path) | ||
| 388 | "Return all node names of SERVICE in D-Bus BUS at object path PATH. | ||
| 389 | It returns a list of strings, which are further object paths of SERVICE." | ||
| 390 | (let ((result (list path))) | ||
| 391 | (dolist (elt | ||
| 392 | (dbus-introspect-get-node-names bus service path) | ||
| 393 | result) | ||
| 394 | (setq elt (expand-file-name elt path)) | ||
| 395 | (setq result | ||
| 396 | (append result (dbus-introspect-get-all-nodes bus service elt)))))) | ||
| 397 | |||
| 398 | (defun dbus-introspect-get-interface-names (bus service path) | ||
| 399 | "Return all interface names of SERVICE in D-Bus BUS at object path PATH. | ||
| 400 | It returns a list of strings. | ||
| 401 | |||
| 402 | There will be always the default interface | ||
| 403 | \"org.freedesktop.DBus.Introspectable\". Another default | ||
| 404 | interface is \"org.freedesktop.DBus.Properties\". If present, | ||
| 405 | \"interface\" objects can also have \"property\" objects as | ||
| 406 | children, beside \"method\" and \"signal\" objects." | ||
| 407 | (let ((object (dbus-introspect-xml bus service path)) | ||
| 408 | result) | ||
| 409 | (dolist (elt (xml-get-children object 'interface) result) | ||
| 410 | (add-to-list | ||
| 411 | 'result (dbus-introspect-get-attribute elt "name") 'append)))) | ||
| 412 | |||
| 413 | (defun dbus-introspect-get-interface (bus service path interface) | ||
| 414 | "Return the INTERFACE of SERVICE in D-Bus BUS at object path PATH. | ||
| 415 | The return value is an XML object. INTERFACE must be a string, | ||
| 416 | element of the list returned by | ||
| 417 | `dbus-introspect-get-interface-names'. The resulting | ||
| 418 | \"interface\" object can contain \"method\", \"signal\", | ||
| 419 | \"property\" and \"annotation\" children." | ||
| 420 | (let ((elt (xml-get-children | ||
| 421 | (dbus-introspect-xml bus service path) 'interface))) | ||
| 422 | (while (and elt | ||
| 423 | (not (string-equal | ||
| 424 | interface | ||
| 425 | (dbus-introspect-get-attribute (car elt) "name")))) | ||
| 426 | (setq elt (cdr elt))) | ||
| 427 | (car elt))) | ||
| 428 | |||
| 429 | (defun dbus-introspect-get-method-names (bus service path interface) | ||
| 430 | "Return a list of strings of all method names of INTERFACE. | ||
| 431 | SERVICE is a service of D-Bus BUS at object path PATH." | ||
| 432 | (let ((object (dbus-introspect-get-interface bus service path interface)) | ||
| 433 | result) | ||
| 434 | (dolist (elt (xml-get-children object 'method) result) | ||
| 435 | (add-to-list | ||
| 436 | 'result (dbus-introspect-get-attribute elt "name") 'append)))) | ||
| 437 | |||
| 438 | (defun dbus-introspect-get-method (bus service path interface method) | ||
| 439 | "Return method METHOD of interface INTERFACE as XML object. | ||
| 440 | It must be located at SERVICE in D-Bus BUS at object path PATH. | ||
| 441 | METHOD must be a string, element of the list returned by | ||
| 442 | `dbus-introspect-get-method-names'. The resulting \"method\" | ||
| 443 | object can contain \"arg\" and \"annotation\" children." | ||
| 444 | (let ((elt (xml-get-children | ||
| 445 | (dbus-introspect-get-interface bus service path interface) | ||
| 446 | 'method))) | ||
| 447 | (while (and elt | ||
| 448 | (not (string-equal | ||
| 449 | method (dbus-introspect-get-attribute (car elt) "name")))) | ||
| 450 | (setq elt (cdr elt))) | ||
| 451 | (car elt))) | ||
| 452 | |||
| 453 | (defun dbus-introspect-get-signal-names (bus service path interface) | ||
| 454 | "Return a list of strings of all signal names of INTERFACE. | ||
| 455 | SERVICE is a service of D-Bus BUS at object path PATH." | ||
| 456 | (let ((object (dbus-introspect-get-interface bus service path interface)) | ||
| 457 | result) | ||
| 458 | (dolist (elt (xml-get-children object 'signal) result) | ||
| 459 | (add-to-list | ||
| 460 | 'result (dbus-introspect-get-attribute elt "name") 'append)))) | ||
| 461 | |||
| 462 | (defun dbus-introspect-get-signal (bus service path interface signal) | ||
| 463 | "Return signal SIGNAL of interface INTERFACE as XML object. | ||
| 464 | It must be located at SERVICE in D-Bus BUS at object path PATH. | ||
| 465 | SIGNAL must be a string, element of the list returned by | ||
| 466 | `dbus-introspect-get-signal-names'. The resulting \"signal\" | ||
| 467 | object can contain \"arg\" and \"annotation\" children." | ||
| 468 | (let ((elt (xml-get-children | ||
| 469 | (dbus-introspect-get-interface bus service path interface) | ||
| 470 | 'signal))) | ||
| 471 | (while (and elt | ||
| 472 | (not (string-equal | ||
| 473 | signal (dbus-introspect-get-attribute (car elt) "name")))) | ||
| 474 | (setq elt (cdr elt))) | ||
| 475 | (car elt))) | ||
| 476 | |||
| 477 | (defun dbus-introspect-get-property-names (bus service path interface) | ||
| 478 | "Return a list of strings of all property names of INTERFACE. | ||
| 479 | SERVICE is a service of D-Bus BUS at object path PATH." | ||
| 480 | (let ((object (dbus-introspect-get-interface bus service path interface)) | ||
| 481 | result) | ||
| 482 | (dolist (elt (xml-get-children object 'property) result) | ||
| 483 | (add-to-list | ||
| 484 | 'result (dbus-introspect-get-attribute elt "name") 'append)))) | ||
| 485 | |||
| 486 | (defun dbus-introspect-get-property (bus service path interface property) | ||
| 487 | "This function returns PROPERTY of INTERFACE as XML object. | ||
| 488 | It must be located at SERVICE in D-Bus BUS at object path PATH. | ||
| 489 | PROPERTY must be a string, element of the list returned by | ||
| 490 | `dbus-introspect-get-property-names'. The resulting PROPERTY | ||
| 491 | object can contain \"annotation\" children." | ||
| 492 | (let ((elt (xml-get-children | ||
| 493 | (dbus-introspect-get-interface bus service path interface) | ||
| 494 | 'property))) | ||
| 495 | (while (and elt | ||
| 496 | (not (string-equal | ||
| 497 | property | ||
| 498 | (dbus-introspect-get-attribute (car elt) "name")))) | ||
| 499 | (setq elt (cdr elt))) | ||
| 500 | (car elt))) | ||
| 501 | |||
| 502 | (defun dbus-introspect-get-annotation-names | ||
| 503 | (bus service path interface &optional name) | ||
| 504 | "Return all annotation names as list of strings. | ||
| 505 | If NAME is `nil', the annotations are children of INTERFACE, | ||
| 506 | otherwise NAME must be a \"method\", \"signal\", or \"property\" | ||
| 507 | object, where the annotations belong to." | ||
| 508 | (let ((object | ||
| 509 | (if name | ||
| 510 | (or (dbus-introspect-get-method bus service path interface name) | ||
| 511 | (dbus-introspect-get-signal bus service path interface name) | ||
| 512 | (dbus-introspect-get-property bus service path interface name)) | ||
| 513 | (dbus-introspect-get-interface bus service path interface))) | ||
| 514 | result) | ||
| 515 | (dolist (elt (xml-get-children object 'annotation) result) | ||
| 516 | (add-to-list | ||
| 517 | 'result (dbus-introspect-get-attribute elt "name") 'append)))) | ||
| 518 | |||
| 519 | (defun dbus-introspect-get-annotation | ||
| 520 | (bus service path interface name annotation) | ||
| 521 | "Return ANNOTATION as XML object. | ||
| 522 | If NAME is `nil', ANNOTATION is a child of INTERFACE, otherwise | ||
| 523 | NAME must be the name of a \"method\", \"signal\", or | ||
| 524 | \"property\" object, where the ANNOTATION belongs to." | ||
| 525 | (let ((elt (xml-get-children | ||
| 526 | (if name | ||
| 527 | (or (dbus-introspect-get-method | ||
| 528 | bus service path interface name) | ||
| 529 | (dbus-introspect-get-signal | ||
| 530 | bus service path interface name) | ||
| 531 | (dbus-introspect-get-property | ||
| 532 | bus service path interface name)) | ||
| 533 | (dbus-introspect-get-interface bus service path interface)) | ||
| 534 | 'annotation))) | ||
| 535 | (while (and elt | ||
| 536 | (not (string-equal | ||
| 537 | annotation | ||
| 538 | (dbus-introspect-get-attribute (car elt) "name")))) | ||
| 539 | (setq elt (cdr elt))) | ||
| 540 | (car elt))) | ||
| 541 | |||
| 542 | (defun dbus-introspect-get-argument-names (bus service path interface name) | ||
| 543 | "Return a list of all argument names as list of strings. | ||
| 544 | NAME must be a \"method\" or \"signal\" object. | ||
| 545 | |||
| 546 | Argument names are optional, the function can return `nil' | ||
| 547 | therefore, even if the method or signal has arguments." | ||
| 548 | (let ((object | ||
| 549 | (or (dbus-introspect-get-method bus service path interface name) | ||
| 550 | (dbus-introspect-get-signal bus service path interface name))) | ||
| 551 | result) | ||
| 552 | (dolist (elt (xml-get-children object 'arg) result) | ||
| 553 | (add-to-list | ||
| 554 | 'result (dbus-introspect-get-attribute elt "name") 'append)))) | ||
| 555 | |||
| 556 | (defun dbus-introspect-get-argument (bus service path interface name arg) | ||
| 557 | "Return argument ARG as XML object. | ||
| 558 | NAME must be a \"method\" or \"signal\" object. ARG must be a | ||
| 559 | string, element of the list returned by `dbus-introspect-get-argument-names'." | ||
| 560 | (let ((elt (xml-get-children | ||
| 561 | (or (dbus-introspect-get-method bus service path interface name) | ||
| 562 | (dbus-introspect-get-signal bus service path interface name)) | ||
| 563 | 'arg))) | ||
| 564 | (while (and elt | ||
| 565 | (not (string-equal | ||
| 566 | arg (dbus-introspect-get-attribute (car elt) "name")))) | ||
| 567 | (setq elt (cdr elt))) | ||
| 568 | (car elt))) | ||
| 569 | |||
| 570 | (defun dbus-introspect-get-signature | ||
| 571 | (bus service path interface name &optional direction) | ||
| 572 | "Return signature of a `method' or `signal', represented by NAME, as string. | ||
| 573 | If NAME is a `method', DIRECTION can be either \"in\" or \"out\". | ||
| 574 | If DIRECTION is `nil', \"in\" is assumed. | ||
| 575 | |||
| 576 | If NAME is a `signal', and DIRECTION is non-`nil', DIRECTION must | ||
| 577 | be \"out\"." | ||
| 578 | ;; For methods, we use "in" as default direction. | ||
| 579 | (let ((object (or (dbus-introspect-get-method | ||
| 580 | bus service path interface name) | ||
| 581 | (dbus-introspect-get-signal | ||
| 582 | bus service path interface name)))) | ||
| 583 | (when (and (string-equal | ||
| 584 | "method" (dbus-introspect-get-attribute object "name")) | ||
| 585 | (not (stringp direction))) | ||
| 586 | (setq direction "in")) | ||
| 587 | ;; In signals, no direction is given. | ||
| 588 | (when (string-equal "signal" (dbus-introspect-get-attribute object "name")) | ||
| 589 | (setq direction nil)) | ||
| 590 | ;; Collect the signatures. | ||
| 591 | (mapconcat | ||
| 592 | '(lambda (x) | ||
| 593 | (let ((arg (dbus-introspect-get-argument | ||
| 594 | bus service path interface name x))) | ||
| 595 | (if (or (not (stringp direction)) | ||
| 596 | (string-equal | ||
| 597 | direction | ||
| 598 | (dbus-introspect-get-attribute arg "direction"))) | ||
| 599 | (dbus-introspect-get-attribute arg "type") | ||
| 600 | ""))) | ||
| 601 | (dbus-introspect-get-argument-names bus service path interface name) | ||
| 602 | ""))) | ||
| 359 | 603 | ||
| 360 | This list represents 3 parameters of SIGNAL. The first parameter | 604 | |
| 361 | is of type string, the second parameter is of type boolean, and | 605 | ;;; D-Bus properties. |
| 362 | the third parameter is of type array of integer. | ||
| 363 | 606 | ||
| 364 | If INTERFACE or SIGNAL do not exist, or if they do not support | 607 | (defun dbus-get-property (bus service path interface property) |
| 365 | the D-Bus method org.freedesktop.DBus.Introspectable.Introspect, | 608 | "Return the value of PROPERTY of INTERFACE. |
| 366 | the function returns nil." | 609 | It will be checked at BUS, SERVICE, PATH. The result can be any |
| 610 | valid D-Bus value, or `nil' if there is no PROPERTY." | ||
| 367 | (dbus-ignore-errors | 611 | (dbus-ignore-errors |
| 368 | (let ((introspect-xml | 612 | ;; We must check, whether the "org.freedesktop.DBus.Properties" |
| 369 | (with-temp-buffer | 613 | ;; interface is supported; otherwise the call blocks. |
| 370 | (insert (dbus-introspect bus interface)) | 614 | (when |
| 371 | (xml-parse-region (point-min) (point-max)))) | 615 | (member |
| 372 | node interfaces signals args result) | 616 | "Get" |
| 373 | ;; Get the root node. | 617 | (dbus-introspect-get-method-names |
| 374 | (setq node (xml-node-name introspect-xml)) | 618 | bus service path "org.freedesktop.DBus.Properties")) |
| 375 | ;; Get all interfaces. | 619 | ;; "Get" returns a variant, so we must use the car. |
| 376 | (setq interfaces (xml-get-children node 'interface)) | 620 | (car |
| 377 | (while interfaces | 621 | (dbus-call-method |
| 378 | (when (string-equal (xml-get-attribute (car interfaces) 'name) | 622 | bus service path dbus-interface-properties |
| 379 | interface) | 623 | "Get" interface property))))) |
| 380 | ;; That's the requested interface. Check for signals. | 624 | |
| 381 | (setq signals (xml-get-children (car interfaces) 'signal)) | 625 | (defun dbus-set-property (bus service path interface property value) |
| 382 | (while signals | 626 | "Set value of PROPERTY of INTERFACE to VALUE. |
| 383 | (when (string-equal (xml-get-attribute (car signals) 'name) signal) | 627 | It will be checked at BUS, SERVICE, PATH. When the value has |
| 384 | ;; The signal we are looking for. | 628 | been set successful, the result is VALUE. Otherwise, `nil' is |
| 385 | (setq args (xml-get-children (car signals) 'arg)) | 629 | returned." |
| 386 | (while args | 630 | (dbus-ignore-errors |
| 387 | (unless (xml-get-attribute (car args) 'type) | 631 | (when |
| 388 | ;; This shouldn't happen, let's escape. | 632 | (and |
| 389 | (signal 'dbus-error nil)) | 633 | ;; We must check, whether the |
| 390 | ;; We append the signature. | 634 | ;; "org.freedesktop.DBus.Properties" interface is supported; |
| 391 | (setq | 635 | ;; otherwise the call blocks. |
| 392 | result (append result | 636 | (member |
| 393 | (list (xml-get-attribute (car args) 'type)))) | 637 | "Set" |
| 394 | (setq args (cdr args))) | 638 | (dbus-introspect-get-method-names |
| 395 | (setq signals nil)) | 639 | bus service path "org.freedesktop.DBus.Properties")) |
| 396 | (setq signals (cdr signals))) | 640 | ;; PROPERTY must be writable. |
| 397 | (setq interfaces nil)) | 641 | (string-equal |
| 398 | (setq interfaces (cdr interfaces))) | 642 | "readwrite" |
| 399 | result))) | 643 | (dbus-introspect-get-attribute |
| 400 | ) ;; (if nil ... | 644 | bus service path interface property) |
| 645 | "access")) | ||
| 646 | ;; "Set" requires a variant. | ||
| 647 | (dbus-call-method | ||
| 648 | bus service path dbus-interface-properties | ||
| 649 | "Set" interface property (list :variant value)) | ||
| 650 | ;; Return VALUE. | ||
| 651 | (dbus-get-property bus service path interface property)))) | ||
| 652 | |||
| 653 | (defun dbus-get-all-properties (bus service path interface) | ||
| 654 | "Return all properties of INTERFACE at BUS, SERVICE, PATH. | ||
| 655 | The result is a list of entries. Every entry is a cons of the | ||
| 656 | name of the property, and its value. If there are no properties, | ||
| 657 | `nil' is returned." | ||
| 658 | ;; "org.freedesktop.DBus.Properties.GetAll" is not supported at | ||
| 659 | ;; all interfaces. Therefore, we do it ourselves. | ||
| 660 | (dbus-ignore-errors | ||
| 661 | (let (result) | ||
| 662 | (dolist (property | ||
| 663 | (dbus-introspect-get-property-names | ||
| 664 | bus service path interface) | ||
| 665 | result) | ||
| 666 | (add-to-list | ||
| 667 | 'result | ||
| 668 | (cons property (dbus-get-property bus service path interface property)) | ||
| 669 | 'append))))) | ||
| 401 | 670 | ||
| 402 | (provide 'dbus) | 671 | (provide 'dbus) |
| 403 | 672 | ||