diff options
| author | Paul Eggert | 2012-05-25 11:19:24 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-05-25 11:19:24 -0700 |
| commit | 42b2a986d9d4b7040fb20c90ec0efeffb78e761a (patch) | |
| tree | d38e7bf5307837f2f38982757f088100de18a64e /src/dbusbind.c | |
| parent | e4d81efc58695c19154d5f6733d91172b4c3e5b7 (diff) | |
| parent | a8d3cbf75d219d7a249fc0623219511179e959da (diff) | |
| download | emacs-42b2a986d9d4b7040fb20c90ec0efeffb78e761a.tar.gz emacs-42b2a986d9d4b7040fb20c90ec0efeffb78e761a.zip | |
Merge from trunk.
Diffstat (limited to 'src/dbusbind.c')
| -rw-r--r-- | src/dbusbind.c | 1848 |
1 files changed, 675 insertions, 1173 deletions
diff --git a/src/dbusbind.c b/src/dbusbind.c index c4e57dad98a..2ed7369c9dc 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c | |||
| @@ -28,19 +28,15 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 28 | #include "keyboard.h" | 28 | #include "keyboard.h" |
| 29 | #include "process.h" | 29 | #include "process.h" |
| 30 | 30 | ||
| 31 | #ifndef DBUS_NUM_MESSAGE_TYPES | ||
| 32 | #define DBUS_NUM_MESSAGE_TYPES 5 | ||
| 33 | #endif | ||
| 34 | |||
| 31 | 35 | ||
| 32 | /* Subroutines. */ | 36 | /* Subroutines. */ |
| 33 | static Lisp_Object Qdbus_init_bus; | 37 | static Lisp_Object Qdbus_init_bus; |
| 34 | static Lisp_Object Qdbus_close_bus; | ||
| 35 | static Lisp_Object Qdbus_get_unique_name; | 38 | static Lisp_Object Qdbus_get_unique_name; |
| 36 | static Lisp_Object Qdbus_call_method; | 39 | static Lisp_Object Qdbus_message_internal; |
| 37 | static Lisp_Object Qdbus_call_method_asynchronously; | ||
| 38 | static Lisp_Object Qdbus_method_return_internal; | ||
| 39 | static Lisp_Object Qdbus_method_error_internal; | ||
| 40 | static Lisp_Object Qdbus_send_signal; | ||
| 41 | static Lisp_Object Qdbus_register_service; | ||
| 42 | static Lisp_Object Qdbus_register_signal; | ||
| 43 | static Lisp_Object Qdbus_register_method; | ||
| 44 | 40 | ||
| 45 | /* D-Bus error symbol. */ | 41 | /* D-Bus error symbol. */ |
| 46 | static Lisp_Object Qdbus_error; | 42 | static Lisp_Object Qdbus_error; |
| @@ -51,17 +47,6 @@ static Lisp_Object QCdbus_system_bus, QCdbus_session_bus; | |||
| 51 | /* Lisp symbol for method call timeout. */ | 47 | /* Lisp symbol for method call timeout. */ |
| 52 | static Lisp_Object QCdbus_timeout; | 48 | static Lisp_Object QCdbus_timeout; |
| 53 | 49 | ||
| 54 | /* Lisp symbols for name request flags. */ | ||
| 55 | static Lisp_Object QCdbus_request_name_allow_replacement; | ||
| 56 | static Lisp_Object QCdbus_request_name_replace_existing; | ||
| 57 | static Lisp_Object QCdbus_request_name_do_not_queue; | ||
| 58 | |||
| 59 | /* Lisp symbols for name request replies. */ | ||
| 60 | static Lisp_Object QCdbus_request_name_reply_primary_owner; | ||
| 61 | static Lisp_Object QCdbus_request_name_reply_in_queue; | ||
| 62 | static Lisp_Object QCdbus_request_name_reply_exists; | ||
| 63 | static Lisp_Object QCdbus_request_name_reply_already_owner; | ||
| 64 | |||
| 65 | /* Lisp symbols of D-Bus types. */ | 50 | /* Lisp symbols of D-Bus types. */ |
| 66 | static Lisp_Object QCdbus_type_byte, QCdbus_type_boolean; | 51 | static Lisp_Object QCdbus_type_byte, QCdbus_type_boolean; |
| 67 | static Lisp_Object QCdbus_type_int16, QCdbus_type_uint16; | 52 | static Lisp_Object QCdbus_type_int16, QCdbus_type_uint16; |
| @@ -75,6 +60,15 @@ static Lisp_Object QCdbus_type_unix_fd; | |||
| 75 | static Lisp_Object QCdbus_type_array, QCdbus_type_variant; | 60 | static Lisp_Object QCdbus_type_array, QCdbus_type_variant; |
| 76 | static Lisp_Object QCdbus_type_struct, QCdbus_type_dict_entry; | 61 | static Lisp_Object QCdbus_type_struct, QCdbus_type_dict_entry; |
| 77 | 62 | ||
| 63 | /* Lisp symbols of objects in `dbus-registered-objects-table'. */ | ||
| 64 | static Lisp_Object QCdbus_registered_serial, QCdbus_registered_method; | ||
| 65 | static Lisp_Object QCdbus_registered_signal; | ||
| 66 | |||
| 67 | /* Alist of D-Bus buses we are polling for messages. | ||
| 68 | The key is the symbol or string of the bus, and the value is the | ||
| 69 | connection address. */ | ||
| 70 | static Lisp_Object xd_registered_buses; | ||
| 71 | |||
| 78 | /* Whether we are reading a D-Bus event. */ | 72 | /* Whether we are reading a D-Bus event. */ |
| 79 | static int xd_in_read_queued_messages = 0; | 73 | static int xd_in_read_queued_messages = 0; |
| 80 | 74 | ||
| @@ -120,14 +114,15 @@ static int xd_in_read_queued_messages = 0; | |||
| 120 | } while (0) | 114 | } while (0) |
| 121 | 115 | ||
| 122 | /* Macros for debugging. In order to enable them, build with | 116 | /* Macros for debugging. In order to enable them, build with |
| 123 | "MYCPPFLAGS='-DDBUS_DEBUG -Wall' make". */ | 117 | "env MYCPPFLAGS='-DDBUS_DEBUG -Wall' make". */ |
| 124 | #ifdef DBUS_DEBUG | 118 | #ifdef DBUS_DEBUG |
| 125 | #define XD_DEBUG_MESSAGE(...) \ | 119 | #define XD_DEBUG_MESSAGE(...) \ |
| 126 | do { \ | 120 | do { \ |
| 127 | char s[1024]; \ | 121 | char s[1024]; \ |
| 128 | snprintf (s, sizeof s, __VA_ARGS__); \ | 122 | snprintf (s, sizeof s, __VA_ARGS__); \ |
| 129 | printf ("%s: %s\n", __func__, s); \ | 123 | if (!noninteractive) \ |
| 130 | message ("%s: %s", __func__, s); \ | 124 | printf ("%s: %s\n", __func__, s); \ |
| 125 | message ("%s: %s", __func__, s); \ | ||
| 131 | } while (0) | 126 | } while (0) |
| 132 | #define XD_DEBUG_VALID_LISP_OBJECT_P(object) \ | 127 | #define XD_DEBUG_VALID_LISP_OBJECT_P(object) \ |
| 133 | do { \ | 128 | do { \ |
| @@ -144,7 +139,7 @@ static int xd_in_read_queued_messages = 0; | |||
| 144 | if (!NILP (Vdbus_debug)) \ | 139 | if (!NILP (Vdbus_debug)) \ |
| 145 | { \ | 140 | { \ |
| 146 | char s[1024]; \ | 141 | char s[1024]; \ |
| 147 | snprintf (s, 1023, __VA_ARGS__); \ | 142 | snprintf (s, sizeof s, __VA_ARGS__); \ |
| 148 | message ("%s: %s", __func__, s); \ | 143 | message ("%s: %s", __func__, s); \ |
| 149 | } \ | 144 | } \ |
| 150 | } while (0) | 145 | } while (0) |
| @@ -241,23 +236,115 @@ xd_symbol_to_dbus_type (Lisp_Object object) | |||
| 241 | #define XD_NEXT_VALUE(object) \ | 236 | #define XD_NEXT_VALUE(object) \ |
| 242 | ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object) | 237 | ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object) |
| 243 | 238 | ||
| 239 | /* Transform the message type to its string representation for debug | ||
| 240 | messages. */ | ||
| 241 | #define XD_MESSAGE_TYPE_TO_STRING(mtype) \ | ||
| 242 | ((mtype == DBUS_MESSAGE_TYPE_INVALID) \ | ||
| 243 | ? "DBUS_MESSAGE_TYPE_INVALID" \ | ||
| 244 | : (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) \ | ||
| 245 | ? "DBUS_MESSAGE_TYPE_METHOD_CALL" \ | ||
| 246 | : (mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) \ | ||
| 247 | ? "DBUS_MESSAGE_TYPE_METHOD_RETURN" \ | ||
| 248 | : (mtype == DBUS_MESSAGE_TYPE_ERROR) \ | ||
| 249 | ? "DBUS_MESSAGE_TYPE_ERROR" \ | ||
| 250 | : "DBUS_MESSAGE_TYPE_SIGNAL") | ||
| 251 | |||
| 252 | /* Transform the object to its string representation for debug | ||
| 253 | messages. */ | ||
| 254 | #define XD_OBJECT_TO_STRING(object) \ | ||
| 255 | SDATA (format2 ("%s", object, Qnil)) | ||
| 256 | |||
| 244 | /* Check whether X is a valid dbus serial number. If valid, set | 257 | /* Check whether X is a valid dbus serial number. If valid, set |
| 245 | SERIAL to its value. Otherwise, signal an error. */ | 258 | SERIAL to its value. Otherwise, signal an error. */ |
| 246 | #define CHECK_DBUS_SERIAL_GET_SERIAL(x, serial) \ | 259 | #define XD_CHECK_DBUS_SERIAL(x, serial) \ |
| 247 | do \ | 260 | do { \ |
| 248 | { \ | 261 | dbus_uint32_t DBUS_SERIAL_MAX = -1; \ |
| 249 | dbus_uint32_t DBUS_SERIAL_MAX = -1; \ | 262 | if (NATNUMP (x) && XINT (x) <= DBUS_SERIAL_MAX) \ |
| 250 | if (NATNUMP (x) && XINT (x) <= DBUS_SERIAL_MAX) \ | 263 | serial = XINT (x); \ |
| 251 | serial = XINT (x); \ | 264 | else if (MOST_POSITIVE_FIXNUM < DBUS_SERIAL_MAX \ |
| 252 | else if (MOST_POSITIVE_FIXNUM < DBUS_SERIAL_MAX \ | 265 | && FLOATP (x) \ |
| 253 | && FLOATP (x) \ | 266 | && 0 <= XFLOAT_DATA (x) \ |
| 254 | && 0 <= XFLOAT_DATA (x) \ | 267 | && XFLOAT_DATA (x) <= DBUS_SERIAL_MAX) \ |
| 255 | && XFLOAT_DATA (x) <= DBUS_SERIAL_MAX) \ | 268 | serial = XFLOAT_DATA (x); \ |
| 256 | serial = XFLOAT_DATA (x); \ | 269 | else \ |
| 257 | else \ | 270 | XD_SIGNAL2 (build_string ("Invalid dbus serial"), x); \ |
| 258 | XD_SIGNAL2 (build_string ("Invalid dbus serial"), x); \ | 271 | } while (0) |
| 259 | } \ | 272 | |
| 260 | while (0) | 273 | #define XD_DBUS_VALIDATE_BUS_ADDRESS(bus) \ |
| 274 | do { \ | ||
| 275 | if (STRINGP (bus)) \ | ||
| 276 | { \ | ||
| 277 | DBusAddressEntry **entries; \ | ||
| 278 | int len; \ | ||
| 279 | DBusError derror; \ | ||
| 280 | dbus_error_init (&derror); \ | ||
| 281 | if (!dbus_parse_address (SSDATA (bus), &entries, &len, &derror)) \ | ||
| 282 | XD_ERROR (derror); \ | ||
| 283 | /* Cleanup. */ \ | ||
| 284 | dbus_error_free (&derror); \ | ||
| 285 | dbus_address_entries_free (entries); \ | ||
| 286 | } \ | ||
| 287 | \ | ||
| 288 | else \ | ||
| 289 | { \ | ||
| 290 | CHECK_SYMBOL (bus); \ | ||
| 291 | if (!(EQ (bus, QCdbus_system_bus) || EQ (bus, QCdbus_session_bus))) \ | ||
| 292 | XD_SIGNAL2 (build_string ("Wrong bus name"), bus); \ | ||
| 293 | /* We do not want to have an autolaunch for the session bus. */ \ | ||
| 294 | if (EQ (bus, QCdbus_session_bus) \ | ||
| 295 | && getenv ("DBUS_SESSION_BUS_ADDRESS") == NULL) \ | ||
| 296 | XD_SIGNAL2 (build_string ("No connection to bus"), bus); \ | ||
| 297 | } \ | ||
| 298 | } while (0) | ||
| 299 | |||
| 300 | #if (HAVE_DBUS_VALIDATE_BUS_NAME || HAVE_DBUS_VALIDATE_PATH \ | ||
| 301 | || XD_DBUS_VALIDATE_OBJECT || HAVE_DBUS_VALIDATE_MEMBER) | ||
| 302 | #define XD_DBUS_VALIDATE_OBJECT(object, func) \ | ||
| 303 | do { \ | ||
| 304 | if (!NILP (object)) \ | ||
| 305 | { \ | ||
| 306 | DBusError derror; \ | ||
| 307 | CHECK_STRING (object); \ | ||
| 308 | dbus_error_init (&derror); \ | ||
| 309 | if (!func (SSDATA (object), &derror)) \ | ||
| 310 | XD_ERROR (derror); \ | ||
| 311 | /* Cleanup. */ \ | ||
| 312 | dbus_error_free (&derror); \ | ||
| 313 | } \ | ||
| 314 | } while (0) | ||
| 315 | #endif | ||
| 316 | |||
| 317 | #if HAVE_DBUS_VALIDATE_BUS_NAME | ||
| 318 | #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \ | ||
| 319 | XD_DBUS_VALIDATE_OBJECT(bus_name, dbus_validate_bus_name); | ||
| 320 | #else | ||
| 321 | #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \ | ||
| 322 | if (!NILP (bus_name)) CHECK_STRING (bus_name); | ||
| 323 | #endif | ||
| 324 | |||
| 325 | #if HAVE_DBUS_VALIDATE_PATH | ||
| 326 | #define XD_DBUS_VALIDATE_PATH(path) \ | ||
| 327 | XD_DBUS_VALIDATE_OBJECT(path, dbus_validate_path); | ||
| 328 | #else | ||
| 329 | #define XD_DBUS_VALIDATE_PATH(path) \ | ||
| 330 | if (!NILP (path)) CHECK_STRING (path); | ||
| 331 | #endif | ||
| 332 | |||
| 333 | #if HAVE_DBUS_VALIDATE_INTERFACE | ||
| 334 | #define XD_DBUS_VALIDATE_INTERFACE(interface) \ | ||
| 335 | XD_DBUS_VALIDATE_OBJECT(interface, dbus_validate_interface); | ||
| 336 | #else | ||
| 337 | #define XD_DBUS_VALIDATE_INTERFACE(interface) \ | ||
| 338 | if (!NILP (interface)) CHECK_STRING (interface); | ||
| 339 | #endif | ||
| 340 | |||
| 341 | #if HAVE_DBUS_VALIDATE_MEMBER | ||
| 342 | #define XD_DBUS_VALIDATE_MEMBER(member) \ | ||
| 343 | XD_DBUS_VALIDATE_OBJECT(member, dbus_validate_member); | ||
| 344 | #else | ||
| 345 | #define XD_DBUS_VALIDATE_MEMBER(member) \ | ||
| 346 | if (!NILP (member)) CHECK_STRING (member); | ||
| 347 | #endif | ||
| 261 | 348 | ||
| 262 | /* Append to SIGNATURE a copy of X, making sure SIGNATURE does | 349 | /* Append to SIGNATURE a copy of X, making sure SIGNATURE does |
| 263 | not become too long. */ | 350 | not become too long. */ |
| @@ -293,11 +380,6 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis | |||
| 293 | { | 380 | { |
| 294 | case DBUS_TYPE_BYTE: | 381 | case DBUS_TYPE_BYTE: |
| 295 | case DBUS_TYPE_UINT16: | 382 | case DBUS_TYPE_UINT16: |
| 296 | case DBUS_TYPE_UINT32: | ||
| 297 | case DBUS_TYPE_UINT64: | ||
| 298 | #ifdef DBUS_TYPE_UNIX_FD | ||
| 299 | case DBUS_TYPE_UNIX_FD: | ||
| 300 | #endif | ||
| 301 | CHECK_NATNUM (object); | 383 | CHECK_NATNUM (object); |
| 302 | sprintf (signature, "%c", dtype); | 384 | sprintf (signature, "%c", dtype); |
| 303 | break; | 385 | break; |
| @@ -309,14 +391,19 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis | |||
| 309 | break; | 391 | break; |
| 310 | 392 | ||
| 311 | case DBUS_TYPE_INT16: | 393 | case DBUS_TYPE_INT16: |
| 312 | case DBUS_TYPE_INT32: | ||
| 313 | case DBUS_TYPE_INT64: | ||
| 314 | CHECK_NUMBER (object); | 394 | CHECK_NUMBER (object); |
| 315 | sprintf (signature, "%c", dtype); | 395 | sprintf (signature, "%c", dtype); |
| 316 | break; | 396 | break; |
| 317 | 397 | ||
| 398 | case DBUS_TYPE_UINT32: | ||
| 399 | case DBUS_TYPE_UINT64: | ||
| 400 | #ifdef DBUS_TYPE_UNIX_FD | ||
| 401 | case DBUS_TYPE_UNIX_FD: | ||
| 402 | #endif | ||
| 403 | case DBUS_TYPE_INT32: | ||
| 404 | case DBUS_TYPE_INT64: | ||
| 318 | case DBUS_TYPE_DOUBLE: | 405 | case DBUS_TYPE_DOUBLE: |
| 319 | CHECK_FLOAT (object); | 406 | CHECK_NUMBER_OR_FLOAT (object); |
| 320 | sprintf (signature, "%c", dtype); | 407 | sprintf (signature, "%c", dtype); |
| 321 | break; | 408 | break; |
| 322 | 409 | ||
| @@ -352,8 +439,8 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis | |||
| 352 | } | 439 | } |
| 353 | 440 | ||
| 354 | /* If the element type is DBUS_TYPE_SIGNATURE, and this is the | 441 | /* If the element type is DBUS_TYPE_SIGNATURE, and this is the |
| 355 | only element, the value of this element is used as he array's | 442 | only element, the value of this element is used as the |
| 356 | element signature. */ | 443 | array's element signature. */ |
| 357 | if ((subtype == DBUS_TYPE_SIGNATURE) | 444 | if ((subtype == DBUS_TYPE_SIGNATURE) |
| 358 | && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt))) | 445 | && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt))) |
| 359 | && NILP (CDR_SAFE (XD_NEXT_VALUE (elt)))) | 446 | && NILP (CDR_SAFE (XD_NEXT_VALUE (elt)))) |
| @@ -451,6 +538,54 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis | |||
| 451 | XD_DEBUG_MESSAGE ("%s", signature); | 538 | XD_DEBUG_MESSAGE ("%s", signature); |
| 452 | } | 539 | } |
| 453 | 540 | ||
| 541 | /* Convert X to a signed integer with bounds LO and HI. */ | ||
| 542 | static intmax_t | ||
| 543 | extract_signed (Lisp_Object x, intmax_t lo, intmax_t hi) | ||
| 544 | { | ||
| 545 | CHECK_NUMBER_OR_FLOAT (x); | ||
| 546 | if (INTEGERP (x)) | ||
| 547 | { | ||
| 548 | if (lo <= XINT (x) && XINT (x) <= hi) | ||
| 549 | return XINT (x); | ||
| 550 | } | ||
| 551 | else | ||
| 552 | { | ||
| 553 | double d = XFLOAT_DATA (x); | ||
| 554 | if (lo <= d && d <= hi) | ||
| 555 | { | ||
| 556 | intmax_t n = d; | ||
| 557 | if (n == d) | ||
| 558 | return n; | ||
| 559 | } | ||
| 560 | } | ||
| 561 | args_out_of_range_3 (x, | ||
| 562 | make_fixnum_or_float (lo), | ||
| 563 | make_fixnum_or_float (hi)); | ||
| 564 | } | ||
| 565 | |||
| 566 | /* Convert X to an unsigned integer with bounds 0 and HI. */ | ||
| 567 | static uintmax_t | ||
| 568 | extract_unsigned (Lisp_Object x, uintmax_t hi) | ||
| 569 | { | ||
| 570 | CHECK_NUMBER_OR_FLOAT (x); | ||
| 571 | if (INTEGERP (x)) | ||
| 572 | { | ||
| 573 | if (0 <= XINT (x) && XINT (x) <= hi) | ||
| 574 | return XINT (x); | ||
| 575 | } | ||
| 576 | else | ||
| 577 | { | ||
| 578 | double d = XFLOAT_DATA (x); | ||
| 579 | if (0 <= d && d <= hi) | ||
| 580 | { | ||
| 581 | uintmax_t n = d; | ||
| 582 | if (n == d) | ||
| 583 | return n; | ||
| 584 | } | ||
| 585 | } | ||
| 586 | args_out_of_range_2 (x, make_fixnum_or_float (hi)); | ||
| 587 | } | ||
| 588 | |||
| 454 | /* Append C value, extracted from Lisp OBJECT, to iteration ITER. | 589 | /* Append C value, extracted from Lisp OBJECT, to iteration ITER. |
| 455 | DTYPE must be a valid DBusType. It is used to convert Lisp | 590 | DTYPE must be a valid DBusType. It is used to convert Lisp |
| 456 | objects, being arguments of `dbus-call-method' or | 591 | objects, being arguments of `dbus-call-method' or |
| @@ -469,7 +604,7 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | |||
| 469 | CHECK_NATNUM (object); | 604 | CHECK_NATNUM (object); |
| 470 | { | 605 | { |
| 471 | unsigned char val = XFASTINT (object) & 0xFF; | 606 | unsigned char val = XFASTINT (object) & 0xFF; |
| 472 | XD_DEBUG_MESSAGE ("%c %d", dtype, val); | 607 | XD_DEBUG_MESSAGE ("%c %u", dtype, val); |
| 473 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 608 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| 474 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); | 609 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); |
| 475 | return; | 610 | return; |
| @@ -488,7 +623,8 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | |||
| 488 | CHECK_TYPE_RANGED_INTEGER (dbus_int16_t, object); | 623 | CHECK_TYPE_RANGED_INTEGER (dbus_int16_t, object); |
| 489 | { | 624 | { |
| 490 | dbus_int16_t val = XINT (object); | 625 | dbus_int16_t val = XINT (object); |
| 491 | XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val); | 626 | int pval = val; |
| 627 | XD_DEBUG_MESSAGE ("%c %d", dtype, pval); | ||
| 492 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 628 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| 493 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); | 629 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); |
| 494 | return; | 630 | return; |
| @@ -498,17 +634,20 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | |||
| 498 | CHECK_TYPE_RANGED_INTEGER (dbus_uint16_t, object); | 634 | CHECK_TYPE_RANGED_INTEGER (dbus_uint16_t, object); |
| 499 | { | 635 | { |
| 500 | dbus_uint16_t val = XFASTINT (object); | 636 | dbus_uint16_t val = XFASTINT (object); |
| 501 | XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val); | 637 | unsigned int pval = val; |
| 638 | XD_DEBUG_MESSAGE ("%c %u", dtype, pval); | ||
| 502 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 639 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| 503 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); | 640 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); |
| 504 | return; | 641 | return; |
| 505 | } | 642 | } |
| 506 | 643 | ||
| 507 | case DBUS_TYPE_INT32: | 644 | case DBUS_TYPE_INT32: |
| 508 | CHECK_TYPE_RANGED_INTEGER (dbus_int32_t, object); | ||
| 509 | { | 645 | { |
| 510 | dbus_int32_t val = XINT (object); | 646 | dbus_int32_t val = extract_signed (object, |
| 511 | XD_DEBUG_MESSAGE ("%c %d", dtype, val); | 647 | TYPE_MINIMUM (dbus_int32_t), |
| 648 | TYPE_MAXIMUM (dbus_int32_t)); | ||
| 649 | int pval = val; | ||
| 650 | XD_DEBUG_MESSAGE ("%c %d", dtype, pval); | ||
| 512 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 651 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| 513 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); | 652 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); |
| 514 | return; | 653 | return; |
| @@ -518,39 +657,43 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | |||
| 518 | #ifdef DBUS_TYPE_UNIX_FD | 657 | #ifdef DBUS_TYPE_UNIX_FD |
| 519 | case DBUS_TYPE_UNIX_FD: | 658 | case DBUS_TYPE_UNIX_FD: |
| 520 | #endif | 659 | #endif |
| 521 | CHECK_TYPE_RANGED_INTEGER (dbus_uint32_t, object); | ||
| 522 | { | 660 | { |
| 523 | dbus_uint32_t val = XFASTINT (object); | 661 | dbus_uint32_t val = extract_unsigned (object, |
| 524 | XD_DEBUG_MESSAGE ("%c %u", dtype, val); | 662 | TYPE_MAXIMUM (dbus_uint32_t)); |
| 663 | unsigned int pval = val; | ||
| 664 | XD_DEBUG_MESSAGE ("%c %u", dtype, pval); | ||
| 525 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 665 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| 526 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); | 666 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); |
| 527 | return; | 667 | return; |
| 528 | } | 668 | } |
| 529 | 669 | ||
| 530 | case DBUS_TYPE_INT64: | 670 | case DBUS_TYPE_INT64: |
| 531 | CHECK_NUMBER (object); | 671 | CHECK_TYPE_RANGED_INTEGER_OR_FLOAT (dbus_int64_t, object); |
| 532 | { | 672 | { |
| 533 | dbus_int64_t val = XINT (object); | 673 | dbus_int64_t val = extract_signed (object, |
| 534 | XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val); | 674 | TYPE_MINIMUM (dbus_int64_t), |
| 675 | TYPE_MAXIMUM (dbus_int64_t)); | ||
| 676 | printmax_t pval = val; | ||
| 677 | XD_DEBUG_MESSAGE ("%c %"pMd, dtype, pval); | ||
| 535 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 678 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| 536 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); | 679 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); |
| 537 | return; | 680 | return; |
| 538 | } | 681 | } |
| 539 | 682 | ||
| 540 | case DBUS_TYPE_UINT64: | 683 | case DBUS_TYPE_UINT64: |
| 541 | CHECK_TYPE_RANGED_INTEGER (dbus_uint64_t, object); | ||
| 542 | { | 684 | { |
| 543 | dbus_uint64_t val = XFASTINT (object); | 685 | dbus_uint64_t val = extract_unsigned (object, |
| 544 | XD_DEBUG_MESSAGE ("%c %"pI"d", dtype, XFASTINT (object)); | 686 | TYPE_MAXIMUM (dbus_uint64_t)); |
| 687 | uprintmax_t pval = val; | ||
| 688 | XD_DEBUG_MESSAGE ("%c %"pMu, dtype, pval); | ||
| 545 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 689 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| 546 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); | 690 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); |
| 547 | return; | 691 | return; |
| 548 | } | 692 | } |
| 549 | 693 | ||
| 550 | case DBUS_TYPE_DOUBLE: | 694 | case DBUS_TYPE_DOUBLE: |
| 551 | CHECK_FLOAT (object); | ||
| 552 | { | 695 | { |
| 553 | double val = XFLOAT_DATA (object); | 696 | double val = extract_float (object); |
| 554 | XD_DEBUG_MESSAGE ("%c %f", dtype, val); | 697 | XD_DEBUG_MESSAGE ("%c %f", dtype, val); |
| 555 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 698 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| 556 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); | 699 | XD_SIGNAL2 (build_string ("Unable to append argument"), object); |
| @@ -614,7 +757,7 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | |||
| 614 | dtype, CAR_SAFE (XD_NEXT_VALUE (object))); | 757 | dtype, CAR_SAFE (XD_NEXT_VALUE (object))); |
| 615 | 758 | ||
| 616 | XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature, | 759 | XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature, |
| 617 | SDATA (format2 ("%s", object, Qnil))); | 760 | XD_OBJECT_TO_STRING (object)); |
| 618 | if (!dbus_message_iter_open_container (iter, dtype, | 761 | if (!dbus_message_iter_open_container (iter, dtype, |
| 619 | signature, &subiter)) | 762 | signature, &subiter)) |
| 620 | XD_SIGNAL3 (build_string ("Cannot open container"), | 763 | XD_SIGNAL3 (build_string ("Cannot open container"), |
| @@ -627,7 +770,7 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | |||
| 627 | dtype, CAR_SAFE (XD_NEXT_VALUE (object))); | 770 | dtype, CAR_SAFE (XD_NEXT_VALUE (object))); |
| 628 | 771 | ||
| 629 | XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature, | 772 | XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature, |
| 630 | SDATA (format2 ("%s", object, Qnil))); | 773 | XD_OBJECT_TO_STRING (object)); |
| 631 | if (!dbus_message_iter_open_container (iter, dtype, | 774 | if (!dbus_message_iter_open_container (iter, dtype, |
| 632 | signature, &subiter)) | 775 | signature, &subiter)) |
| 633 | XD_SIGNAL3 (build_string ("Cannot open container"), | 776 | XD_SIGNAL3 (build_string ("Cannot open container"), |
| @@ -637,8 +780,7 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter) | |||
| 637 | case DBUS_TYPE_STRUCT: | 780 | case DBUS_TYPE_STRUCT: |
| 638 | case DBUS_TYPE_DICT_ENTRY: | 781 | case DBUS_TYPE_DICT_ENTRY: |
| 639 | /* These containers do not require a signature. */ | 782 | /* These containers do not require a signature. */ |
| 640 | XD_DEBUG_MESSAGE ("%c %s", dtype, | 783 | XD_DEBUG_MESSAGE ("%c %s", dtype, XD_OBJECT_TO_STRING (object)); |
| 641 | SDATA (format2 ("%s", object, Qnil))); | ||
| 642 | if (!dbus_message_iter_open_container (iter, dtype, NULL, &subiter)) | 784 | if (!dbus_message_iter_open_container (iter, dtype, NULL, &subiter)) |
| 643 | XD_SIGNAL2 (build_string ("Cannot open container"), | 785 | XD_SIGNAL2 (build_string ("Cannot open container"), |
| 644 | make_number (dtype)); | 786 | make_number (dtype)); |
| @@ -678,7 +820,7 @@ xd_retrieve_arg (unsigned int dtype, DBusMessageIter *iter) | |||
| 678 | unsigned int val; | 820 | unsigned int val; |
| 679 | dbus_message_iter_get_basic (iter, &val); | 821 | dbus_message_iter_get_basic (iter, &val); |
| 680 | val = val & 0xFF; | 822 | val = val & 0xFF; |
| 681 | XD_DEBUG_MESSAGE ("%c %d", dtype, val); | 823 | XD_DEBUG_MESSAGE ("%c %u", dtype, val); |
| 682 | return make_number (val); | 824 | return make_number (val); |
| 683 | } | 825 | } |
| 684 | 826 | ||
| @@ -693,24 +835,30 @@ xd_retrieve_arg (unsigned int dtype, DBusMessageIter *iter) | |||
| 693 | case DBUS_TYPE_INT16: | 835 | case DBUS_TYPE_INT16: |
| 694 | { | 836 | { |
| 695 | dbus_int16_t val; | 837 | dbus_int16_t val; |
| 838 | int pval; | ||
| 696 | dbus_message_iter_get_basic (iter, &val); | 839 | dbus_message_iter_get_basic (iter, &val); |
| 697 | XD_DEBUG_MESSAGE ("%c %d", dtype, val); | 840 | pval = val; |
| 841 | XD_DEBUG_MESSAGE ("%c %d", dtype, pval); | ||
| 698 | return make_number (val); | 842 | return make_number (val); |
| 699 | } | 843 | } |
| 700 | 844 | ||
| 701 | case DBUS_TYPE_UINT16: | 845 | case DBUS_TYPE_UINT16: |
| 702 | { | 846 | { |
| 703 | dbus_uint16_t val; | 847 | dbus_uint16_t val; |
| 848 | int pval; | ||
| 704 | dbus_message_iter_get_basic (iter, &val); | 849 | dbus_message_iter_get_basic (iter, &val); |
| 705 | XD_DEBUG_MESSAGE ("%c %d", dtype, val); | 850 | pval = val; |
| 851 | XD_DEBUG_MESSAGE ("%c %d", dtype, pval); | ||
| 706 | return make_number (val); | 852 | return make_number (val); |
| 707 | } | 853 | } |
| 708 | 854 | ||
| 709 | case DBUS_TYPE_INT32: | 855 | case DBUS_TYPE_INT32: |
| 710 | { | 856 | { |
| 711 | dbus_int32_t val; | 857 | dbus_int32_t val; |
| 858 | int pval; | ||
| 712 | dbus_message_iter_get_basic (iter, &val); | 859 | dbus_message_iter_get_basic (iter, &val); |
| 713 | XD_DEBUG_MESSAGE ("%c %d", dtype, val); | 860 | pval = val; |
| 861 | XD_DEBUG_MESSAGE ("%c %d", dtype, pval); | ||
| 714 | return make_fixnum_or_float (val); | 862 | return make_fixnum_or_float (val); |
| 715 | } | 863 | } |
| 716 | 864 | ||
| @@ -720,24 +868,30 @@ xd_retrieve_arg (unsigned int dtype, DBusMessageIter *iter) | |||
| 720 | #endif | 868 | #endif |
| 721 | { | 869 | { |
| 722 | dbus_uint32_t val; | 870 | dbus_uint32_t val; |
| 871 | unsigned int pval = val; | ||
| 723 | dbus_message_iter_get_basic (iter, &val); | 872 | dbus_message_iter_get_basic (iter, &val); |
| 724 | XD_DEBUG_MESSAGE ("%c %d", dtype, val); | 873 | pval = val; |
| 874 | XD_DEBUG_MESSAGE ("%c %u", dtype, pval); | ||
| 725 | return make_fixnum_or_float (val); | 875 | return make_fixnum_or_float (val); |
| 726 | } | 876 | } |
| 727 | 877 | ||
| 728 | case DBUS_TYPE_INT64: | 878 | case DBUS_TYPE_INT64: |
| 729 | { | 879 | { |
| 730 | dbus_int64_t val; | 880 | dbus_int64_t val; |
| 881 | printmax_t pval; | ||
| 731 | dbus_message_iter_get_basic (iter, &val); | 882 | dbus_message_iter_get_basic (iter, &val); |
| 732 | XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val); | 883 | pval = val; |
| 884 | XD_DEBUG_MESSAGE ("%c %"pMd, dtype, pval); | ||
| 733 | return make_fixnum_or_float (val); | 885 | return make_fixnum_or_float (val); |
| 734 | } | 886 | } |
| 735 | 887 | ||
| 736 | case DBUS_TYPE_UINT64: | 888 | case DBUS_TYPE_UINT64: |
| 737 | { | 889 | { |
| 738 | dbus_uint64_t val; | 890 | dbus_uint64_t val; |
| 891 | uprintmax_t pval; | ||
| 739 | dbus_message_iter_get_basic (iter, &val); | 892 | dbus_message_iter_get_basic (iter, &val); |
| 740 | XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val); | 893 | pval = val; |
| 894 | XD_DEBUG_MESSAGE ("%c %"pMd, dtype, pval); | ||
| 741 | return make_fixnum_or_float (val); | 895 | return make_fixnum_or_float (val); |
| 742 | } | 896 | } |
| 743 | 897 | ||
| @@ -777,7 +931,7 @@ xd_retrieve_arg (unsigned int dtype, DBusMessageIter *iter) | |||
| 777 | result = Fcons (xd_retrieve_arg (subtype, &subiter), result); | 931 | result = Fcons (xd_retrieve_arg (subtype, &subiter), result); |
| 778 | dbus_message_iter_next (&subiter); | 932 | dbus_message_iter_next (&subiter); |
| 779 | } | 933 | } |
| 780 | XD_DEBUG_MESSAGE ("%c %s", dtype, SDATA (format2 ("%s", result, Qnil))); | 934 | XD_DEBUG_MESSAGE ("%c %s", dtype, XD_OBJECT_TO_STRING (result)); |
| 781 | RETURN_UNGCPRO (Fnreverse (result)); | 935 | RETURN_UNGCPRO (Fnreverse (result)); |
| 782 | } | 936 | } |
| 783 | 937 | ||
| @@ -787,85 +941,37 @@ xd_retrieve_arg (unsigned int dtype, DBusMessageIter *iter) | |||
| 787 | } | 941 | } |
| 788 | } | 942 | } |
| 789 | 943 | ||
| 790 | /* Initialize D-Bus connection. BUS is either a Lisp symbol, :system | 944 | /* Return the number of references of the shared CONNECTION. */ |
| 791 | or :session, or a string denoting the bus address. It tells which | 945 | static int |
| 792 | D-Bus to initialize. If RAISE_ERROR is non-zero, signal an error | 946 | xd_get_connection_references (DBusConnection *connection) |
| 793 | when the connection cannot be initialized. */ | 947 | { |
| 948 | ptrdiff_t *refcount; | ||
| 949 | |||
| 950 | /* We cannot access the DBusConnection structure, it is not public. | ||
| 951 | But we know, that the reference counter is the first field in | ||
| 952 | that structure. */ | ||
| 953 | refcount = (void *) &connection; | ||
| 954 | refcount = (void *) *refcount; | ||
| 955 | return *refcount; | ||
| 956 | } | ||
| 957 | |||
| 958 | /* Return D-Bus connection address. BUS is either a Lisp symbol, | ||
| 959 | :system or :session, or a string denoting the bus address. */ | ||
| 794 | static DBusConnection * | 960 | static DBusConnection * |
| 795 | xd_initialize (Lisp_Object bus, int raise_error) | 961 | xd_get_connection_address (Lisp_Object bus) |
| 796 | { | 962 | { |
| 797 | DBusConnection *connection; | 963 | DBusConnection *connection; |
| 798 | DBusError derror; | 964 | Lisp_Object val; |
| 799 | |||
| 800 | /* Parameter check. */ | ||
| 801 | if (!STRINGP (bus)) | ||
| 802 | { | ||
| 803 | CHECK_SYMBOL (bus); | ||
| 804 | if (!(EQ (bus, QCdbus_system_bus) || EQ (bus, QCdbus_session_bus))) | ||
| 805 | { | ||
| 806 | if (raise_error) | ||
| 807 | XD_SIGNAL2 (build_string ("Wrong bus name"), bus); | ||
| 808 | else | ||
| 809 | return NULL; | ||
| 810 | } | ||
| 811 | 965 | ||
| 812 | /* We do not want to have an autolaunch for the session bus. */ | 966 | val = CDR_SAFE (Fassoc (bus, xd_registered_buses)); |
| 813 | if (EQ (bus, QCdbus_session_bus) | 967 | if (NILP (val)) |
| 814 | && getenv ("DBUS_SESSION_BUS_ADDRESS") == NULL) | 968 | XD_SIGNAL2 (build_string ("No connection to bus"), bus); |
| 815 | { | ||
| 816 | if (raise_error) | ||
| 817 | XD_SIGNAL2 (build_string ("No connection to bus"), bus); | ||
| 818 | else | ||
| 819 | return NULL; | ||
| 820 | } | ||
| 821 | } | ||
| 822 | |||
| 823 | /* Open a connection to the bus. */ | ||
| 824 | dbus_error_init (&derror); | ||
| 825 | |||
| 826 | if (STRINGP (bus)) | ||
| 827 | connection = dbus_connection_open (SSDATA (bus), &derror); | ||
| 828 | else | 969 | else |
| 829 | if (EQ (bus, QCdbus_system_bus)) | 970 | connection = (DBusConnection *) (intptr_t) XFASTINT (val); |
| 830 | connection = dbus_bus_get (DBUS_BUS_SYSTEM, &derror); | ||
| 831 | else | ||
| 832 | connection = dbus_bus_get (DBUS_BUS_SESSION, &derror); | ||
| 833 | |||
| 834 | if (dbus_error_is_set (&derror)) | ||
| 835 | { | ||
| 836 | if (raise_error) | ||
| 837 | XD_ERROR (derror); | ||
| 838 | else | ||
| 839 | connection = NULL; | ||
| 840 | } | ||
| 841 | 971 | ||
| 842 | /* If it is not the system or session bus, we must register | 972 | if (!dbus_connection_get_is_connected (connection)) |
| 843 | ourselves. Otherwise, we have called dbus_bus_get, which has | ||
| 844 | configured us to exit if the connection closes - we undo this | ||
| 845 | setting. */ | ||
| 846 | if (connection != NULL) | ||
| 847 | { | ||
| 848 | if (STRINGP (bus)) | ||
| 849 | dbus_bus_register (connection, &derror); | ||
| 850 | else | ||
| 851 | dbus_connection_set_exit_on_disconnect (connection, FALSE); | ||
| 852 | } | ||
| 853 | |||
| 854 | if (dbus_error_is_set (&derror)) | ||
| 855 | { | ||
| 856 | if (raise_error) | ||
| 857 | XD_ERROR (derror); | ||
| 858 | else | ||
| 859 | connection = NULL; | ||
| 860 | } | ||
| 861 | |||
| 862 | if (connection == NULL && raise_error) | ||
| 863 | XD_SIGNAL2 (build_string ("No connection to bus"), bus); | 973 | XD_SIGNAL2 (build_string ("No connection to bus"), bus); |
| 864 | 974 | ||
| 865 | /* Cleanup. */ | ||
| 866 | dbus_error_free (&derror); | ||
| 867 | |||
| 868 | /* Return the result. */ | ||
| 869 | return connection; | 975 | return connection; |
| 870 | } | 976 | } |
| 871 | 977 | ||
| @@ -896,8 +1002,8 @@ xd_add_watch (DBusWatch *watch, void *data) | |||
| 896 | int fd = xd_find_watch_fd (watch); | 1002 | int fd = xd_find_watch_fd (watch); |
| 897 | 1003 | ||
| 898 | XD_DEBUG_MESSAGE ("fd %d, write %d, enabled %d", | 1004 | XD_DEBUG_MESSAGE ("fd %d, write %d, enabled %d", |
| 899 | fd, flags & DBUS_WATCH_WRITABLE, | 1005 | fd, flags & DBUS_WATCH_WRITABLE, |
| 900 | dbus_watch_get_enabled (watch)); | 1006 | dbus_watch_get_enabled (watch)); |
| 901 | 1007 | ||
| 902 | if (fd == -1) | 1008 | if (fd == -1) |
| 903 | return FALSE; | 1009 | return FALSE; |
| @@ -929,8 +1035,8 @@ xd_remove_watch (DBusWatch *watch, void *data) | |||
| 929 | /* Unset session environment. */ | 1035 | /* Unset session environment. */ |
| 930 | if (XSYMBOL (QCdbus_session_bus) == data) | 1036 | if (XSYMBOL (QCdbus_session_bus) == data) |
| 931 | { | 1037 | { |
| 932 | XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS"); | 1038 | // XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS"); |
| 933 | unsetenv ("DBUS_SESSION_BUS_ADDRESS"); | 1039 | // unsetenv ("DBUS_SESSION_BUS_ADDRESS"); |
| 934 | } | 1040 | } |
| 935 | 1041 | ||
| 936 | if (flags & DBUS_WATCH_WRITABLE) | 1042 | if (flags & DBUS_WATCH_WRITABLE) |
| @@ -949,23 +1055,111 @@ xd_toggle_watch (DBusWatch *watch, void *data) | |||
| 949 | xd_remove_watch (watch, data); | 1055 | xd_remove_watch (watch, data); |
| 950 | } | 1056 | } |
| 951 | 1057 | ||
| 952 | DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0, | 1058 | /* Close connection to D-Bus BUS. */ |
| 953 | doc: /* Initialize connection to D-Bus BUS. */) | 1059 | static void |
| 954 | (Lisp_Object bus) | 1060 | xd_close_bus (Lisp_Object bus) |
| 1061 | { | ||
| 1062 | DBusConnection *connection; | ||
| 1063 | Lisp_Object val; | ||
| 1064 | |||
| 1065 | /* Check whether we are connected. */ | ||
| 1066 | val = Fassoc (bus, xd_registered_buses); | ||
| 1067 | if (NILP (val)) | ||
| 1068 | return; | ||
| 1069 | |||
| 1070 | /* Retrieve bus address. */ | ||
| 1071 | connection = xd_get_connection_address (bus); | ||
| 1072 | |||
| 1073 | /* Close connection, if there isn't another shared application. */ | ||
| 1074 | if (xd_get_connection_references (connection) == 1) | ||
| 1075 | { | ||
| 1076 | XD_DEBUG_MESSAGE ("Close connection to bus %s", | ||
| 1077 | XD_OBJECT_TO_STRING (bus)); | ||
| 1078 | dbus_connection_close (connection); | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | /* Decrement reference count. */ | ||
| 1082 | dbus_connection_unref (connection); | ||
| 1083 | |||
| 1084 | /* Remove bus from list of registered buses. */ | ||
| 1085 | xd_registered_buses = Fdelete (val, xd_registered_buses); | ||
| 1086 | |||
| 1087 | /* Return. */ | ||
| 1088 | return; | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 2, 0, | ||
| 1092 | doc: /* Establish the connection to D-Bus BUS. | ||
| 1093 | |||
| 1094 | BUS can be either the symbol `:system' or the symbol `:session', or it | ||
| 1095 | can be a string denoting the address of the corresponding bus. For | ||
| 1096 | the system and session buses, this function is called when loading | ||
| 1097 | `dbus.el', there is no need to call it again. | ||
| 1098 | |||
| 1099 | The function returns a number, which counts the connections this Emacs | ||
| 1100 | session has established to the BUS under the same unique name (see | ||
| 1101 | `dbus-get-unique-name'). It depends on the libraries Emacs is linked | ||
| 1102 | with, and on the environment Emacs is running. For example, if Emacs | ||
| 1103 | is linked with the gtk toolkit, and it runs in a GTK-aware environment | ||
| 1104 | like Gnome, another connection might already be established. | ||
| 1105 | |||
| 1106 | When PRIVATE is non-nil, a new connection is established instead of | ||
| 1107 | reusing an existing one. It results in a new unique name at the bus. | ||
| 1108 | This can be used, if it is necessary to distinguish from another | ||
| 1109 | connection used in the same Emacs process, like the one established by | ||
| 1110 | GTK+. It should be used with care for at least the `:system' and | ||
| 1111 | `:session' buses, because other Emacs Lisp packages might already use | ||
| 1112 | this connection to those buses. */) | ||
| 1113 | (Lisp_Object bus, Lisp_Object private) | ||
| 955 | { | 1114 | { |
| 956 | DBusConnection *connection; | 1115 | DBusConnection *connection; |
| 957 | void *busp; | 1116 | DBusError derror; |
| 1117 | Lisp_Object val; | ||
| 1118 | int refcount; | ||
| 958 | 1119 | ||
| 959 | /* Check parameter. */ | 1120 | /* Check parameter. */ |
| 960 | if (SYMBOLP (bus)) | 1121 | XD_DBUS_VALIDATE_BUS_ADDRESS (bus); |
| 961 | busp = XSYMBOL (bus); | 1122 | |
| 962 | else if (STRINGP (bus)) | 1123 | /* Close bus if it is already open. */ |
| 963 | busp = XSTRING (bus); | 1124 | xd_close_bus (bus); |
| 1125 | |||
| 1126 | /* Initialize. */ | ||
| 1127 | dbus_error_init (&derror); | ||
| 1128 | |||
| 1129 | /* Open the connection. */ | ||
| 1130 | if (STRINGP (bus)) | ||
| 1131 | if (NILP (private)) | ||
| 1132 | connection = dbus_connection_open (SSDATA (bus), &derror); | ||
| 1133 | else | ||
| 1134 | connection = dbus_connection_open_private (SSDATA (bus), &derror); | ||
| 1135 | |||
| 1136 | else | ||
| 1137 | if (NILP (private)) | ||
| 1138 | connection = dbus_bus_get (EQ (bus, QCdbus_system_bus) | ||
| 1139 | ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, | ||
| 1140 | &derror); | ||
| 1141 | else | ||
| 1142 | connection = dbus_bus_get_private (EQ (bus, QCdbus_system_bus) | ||
| 1143 | ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, | ||
| 1144 | &derror); | ||
| 1145 | |||
| 1146 | if (dbus_error_is_set (&derror)) | ||
| 1147 | XD_ERROR (derror); | ||
| 1148 | |||
| 1149 | if (connection == NULL) | ||
| 1150 | XD_SIGNAL2 (build_string ("No connection to bus"), bus); | ||
| 1151 | |||
| 1152 | /* If it is not the system or session bus, we must register | ||
| 1153 | ourselves. Otherwise, we have called dbus_bus_get, which has | ||
| 1154 | configured us to exit if the connection closes - we undo this | ||
| 1155 | setting. */ | ||
| 1156 | if (STRINGP (bus)) | ||
| 1157 | dbus_bus_register (connection, &derror); | ||
| 964 | else | 1158 | else |
| 965 | wrong_type_argument (intern ("D-Bus"), bus); | 1159 | dbus_connection_set_exit_on_disconnect (connection, FALSE); |
| 966 | 1160 | ||
| 967 | /* Open a connection to the bus. */ | 1161 | if (dbus_error_is_set (&derror)) |
| 968 | connection = xd_initialize (bus, TRUE); | 1162 | XD_ERROR (derror); |
| 969 | 1163 | ||
| 970 | /* Add the watch functions. We pass also the bus as data, in order | 1164 | /* Add the watch functions. We pass also the bus as data, in order |
| 971 | to distinguish between the buses in xd_remove_watch. */ | 1165 | to distinguish between the buses in xd_remove_watch. */ |
| @@ -973,36 +1167,27 @@ DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0, | |||
| 973 | xd_add_watch, | 1167 | xd_add_watch, |
| 974 | xd_remove_watch, | 1168 | xd_remove_watch, |
| 975 | xd_toggle_watch, | 1169 | xd_toggle_watch, |
| 976 | busp, NULL)) | 1170 | SYMBOLP (bus) |
| 1171 | ? (void *) XSYMBOL (bus) | ||
| 1172 | : (void *) XSTRING (bus), | ||
| 1173 | NULL)) | ||
| 977 | XD_SIGNAL1 (build_string ("Cannot add watch functions")); | 1174 | XD_SIGNAL1 (build_string ("Cannot add watch functions")); |
| 978 | 1175 | ||
| 979 | /* Add bus to list of registered buses. */ | 1176 | /* Add bus to list of registered buses. */ |
| 980 | Vdbus_registered_buses = Fcons (bus, Vdbus_registered_buses); | 1177 | XSETFASTINT (val, (intptr_t) connection); |
| 1178 | xd_registered_buses = Fcons (Fcons (bus, val), xd_registered_buses); | ||
| 981 | 1179 | ||
| 982 | /* We do not want to abort. */ | 1180 | /* We do not want to abort. */ |
| 983 | putenv ((char *) "DBUS_FATAL_WARNINGS=0"); | 1181 | putenv ((char *) "DBUS_FATAL_WARNINGS=0"); |
| 984 | 1182 | ||
| 985 | /* Return. */ | 1183 | /* Cleanup. */ |
| 986 | return Qnil; | 1184 | dbus_error_free (&derror); |
| 987 | } | ||
| 988 | |||
| 989 | DEFUN ("dbus-close-bus", Fdbus_close_bus, Sdbus_close_bus, 1, 1, 0, | ||
| 990 | doc: /* Close connection to D-Bus BUS. */) | ||
| 991 | (Lisp_Object bus) | ||
| 992 | { | ||
| 993 | DBusConnection *connection; | ||
| 994 | |||
| 995 | /* Open a connection to the bus. */ | ||
| 996 | connection = xd_initialize (bus, TRUE); | ||
| 997 | |||
| 998 | /* Decrement reference count to the bus. */ | ||
| 999 | dbus_connection_unref (connection); | ||
| 1000 | |||
| 1001 | /* Remove bus from list of registered buses. */ | ||
| 1002 | Vdbus_registered_buses = Fdelete (bus, Vdbus_registered_buses); | ||
| 1003 | 1185 | ||
| 1004 | /* Return. */ | 1186 | /* Return reference counter. */ |
| 1005 | return Qnil; | 1187 | refcount = xd_get_connection_references (connection); |
| 1188 | XD_DEBUG_MESSAGE ("Bus %s, Reference counter %d", | ||
| 1189 | XD_OBJECT_TO_STRING (bus), refcount); | ||
| 1190 | return make_number (refcount); | ||
| 1006 | } | 1191 | } |
| 1007 | 1192 | ||
| 1008 | DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name, | 1193 | DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name, |
| @@ -1013,8 +1198,11 @@ DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name, | |||
| 1013 | DBusConnection *connection; | 1198 | DBusConnection *connection; |
| 1014 | const char *name; | 1199 | const char *name; |
| 1015 | 1200 | ||
| 1016 | /* Open a connection to the bus. */ | 1201 | /* Check parameter. */ |
| 1017 | connection = xd_initialize (bus, TRUE); | 1202 | XD_DBUS_VALIDATE_BUS_ADDRESS (bus); |
| 1203 | |||
| 1204 | /* Retrieve bus address. */ | ||
| 1205 | connection = xd_get_connection_address (bus); | ||
| 1018 | 1206 | ||
| 1019 | /* Request the name. */ | 1207 | /* Request the name. */ |
| 1020 | name = dbus_bus_get_unique_name (connection); | 1208 | name = dbus_bus_get_unique_name (connection); |
| @@ -1025,341 +1213,243 @@ DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name, | |||
| 1025 | return build_string (name); | 1213 | return build_string (name); |
| 1026 | } | 1214 | } |
| 1027 | 1215 | ||
| 1028 | DEFUN ("dbus-call-method", Fdbus_call_method, Sdbus_call_method, 5, MANY, 0, | 1216 | DEFUN ("dbus-message-internal", Fdbus_message_internal, Sdbus_message_internal, |
| 1029 | doc: /* Call METHOD on the D-Bus BUS. | 1217 | 4, MANY, 0, |
| 1030 | 1218 | doc: /* Send a D-Bus message. | |
| 1031 | BUS is either a Lisp symbol, `:system' or `:session', or a string | 1219 | This is an internal function, it shall not be used outside dbus.el. |
| 1032 | denoting the bus address. | 1220 | |
| 1033 | 1221 | The following usages are expected: | |
| 1034 | SERVICE is the D-Bus service name to be used. PATH is the D-Bus | 1222 | |
| 1035 | object path SERVICE is registered at. INTERFACE is an interface | 1223 | `dbus-call-method', `dbus-call-method-asynchronously': |
| 1036 | offered by SERVICE. It must provide METHOD. | 1224 | \(dbus-message-internal |
| 1037 | 1225 | dbus-message-type-method-call BUS SERVICE PATH INTERFACE METHOD HANDLER | |
| 1038 | If the parameter `:timeout' is given, the following integer TIMEOUT | 1226 | &optional :timeout TIMEOUT &rest ARGS) |
| 1039 | specifies the maximum number of milliseconds the method call must | 1227 | |
| 1040 | return. The default value is 25,000. If the method call doesn't | 1228 | `dbus-send-signal': |
| 1041 | return in time, a D-Bus error is raised. | 1229 | \(dbus-message-internal |
| 1042 | 1230 | dbus-message-type-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) | |
| 1043 | All other arguments ARGS are passed to METHOD as arguments. They are | 1231 | |
| 1044 | converted into D-Bus types via the following rules: | 1232 | `dbus-method-return-internal': |
| 1045 | 1233 | \(dbus-message-internal | |
| 1046 | t and nil => DBUS_TYPE_BOOLEAN | 1234 | dbus-message-type-method-return BUS SERVICE SERIAL &rest ARGS) |
| 1047 | number => DBUS_TYPE_UINT32 | 1235 | |
| 1048 | integer => DBUS_TYPE_INT32 | 1236 | `dbus-method-error-internal': |
| 1049 | float => DBUS_TYPE_DOUBLE | 1237 | \(dbus-message-internal |
| 1050 | string => DBUS_TYPE_STRING | 1238 | dbus-message-type-error BUS SERVICE SERIAL &rest ARGS) |
| 1051 | list => DBUS_TYPE_ARRAY | 1239 | |
| 1052 | 1240 | usage: (dbus-message-internal &rest REST) */) | |
| 1053 | All arguments can be preceded by a type symbol. For details about | ||
| 1054 | type symbols, see Info node `(dbus)Type Conversion'. | ||
| 1055 | |||
| 1056 | `dbus-call-method' returns the resulting values of METHOD as a list of | ||
| 1057 | Lisp objects. The type conversion happens the other direction as for | ||
| 1058 | input arguments. It follows the mapping rules: | ||
| 1059 | |||
| 1060 | DBUS_TYPE_BOOLEAN => t or nil | ||
| 1061 | DBUS_TYPE_BYTE => number | ||
| 1062 | DBUS_TYPE_UINT16 => number | ||
| 1063 | DBUS_TYPE_INT16 => integer | ||
| 1064 | DBUS_TYPE_UINT32 => number or float | ||
| 1065 | DBUS_TYPE_UNIX_FD => number or float | ||
| 1066 | DBUS_TYPE_INT32 => integer or float | ||
| 1067 | DBUS_TYPE_UINT64 => number or float | ||
| 1068 | DBUS_TYPE_INT64 => integer or float | ||
| 1069 | DBUS_TYPE_DOUBLE => float | ||
| 1070 | DBUS_TYPE_STRING => string | ||
| 1071 | DBUS_TYPE_OBJECT_PATH => string | ||
| 1072 | DBUS_TYPE_SIGNATURE => string | ||
| 1073 | DBUS_TYPE_ARRAY => list | ||
| 1074 | DBUS_TYPE_VARIANT => list | ||
| 1075 | DBUS_TYPE_STRUCT => list | ||
| 1076 | DBUS_TYPE_DICT_ENTRY => list | ||
| 1077 | |||
| 1078 | Example: | ||
| 1079 | |||
| 1080 | \(dbus-call-method | ||
| 1081 | :session "org.gnome.seahorse" "/org/gnome/seahorse/keys/openpgp" | ||
| 1082 | "org.gnome.seahorse.Keys" "GetKeyField" | ||
| 1083 | "openpgp:657984B8C7A966DD" "simple-name") | ||
| 1084 | |||
| 1085 | => (t ("Philip R. Zimmermann")) | ||
| 1086 | |||
| 1087 | If the result of the METHOD call is just one value, the converted Lisp | ||
| 1088 | object is returned instead of a list containing this single Lisp object. | ||
| 1089 | |||
| 1090 | \(dbus-call-method | ||
| 1091 | :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer" | ||
| 1092 | "org.freedesktop.Hal.Device" "GetPropertyString" | ||
| 1093 | "system.kernel.machine") | ||
| 1094 | |||
| 1095 | => "i686" | ||
| 1096 | |||
| 1097 | usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &optional :timeout TIMEOUT &rest ARGS) */) | ||
| 1098 | (ptrdiff_t nargs, Lisp_Object *args) | 1241 | (ptrdiff_t nargs, Lisp_Object *args) |
| 1099 | { | 1242 | { |
| 1100 | Lisp_Object bus, service, path, interface, method; | 1243 | Lisp_Object message_type, bus, service, handler; |
| 1244 | Lisp_Object path = Qnil; | ||
| 1245 | Lisp_Object interface = Qnil; | ||
| 1246 | Lisp_Object member = Qnil; | ||
| 1101 | Lisp_Object result; | 1247 | Lisp_Object result; |
| 1102 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 1248 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; |
| 1103 | DBusConnection *connection; | 1249 | DBusConnection *connection; |
| 1104 | DBusMessage *dmessage; | 1250 | DBusMessage *dmessage; |
| 1105 | DBusMessage *reply; | ||
| 1106 | DBusMessageIter iter; | 1251 | DBusMessageIter iter; |
| 1107 | DBusError derror; | ||
| 1108 | unsigned int dtype; | 1252 | unsigned int dtype; |
| 1253 | unsigned int mtype; | ||
| 1254 | dbus_uint32_t serial = 0; | ||
| 1255 | unsigned int ui_serial; | ||
| 1109 | int timeout = -1; | 1256 | int timeout = -1; |
| 1110 | ptrdiff_t i = 5; | 1257 | ptrdiff_t count; |
| 1111 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; | 1258 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; |
| 1112 | 1259 | ||
| 1260 | /* Initialize parameters. */ | ||
| 1261 | message_type = args[0]; | ||
| 1262 | bus = args[1]; | ||
| 1263 | service = args[2]; | ||
| 1264 | handler = Qnil; | ||
| 1265 | |||
| 1266 | CHECK_NATNUM (message_type); | ||
| 1267 | mtype = XFASTINT (message_type); | ||
| 1268 | if ((mtype <= DBUS_MESSAGE_TYPE_INVALID) || (mtype >= DBUS_NUM_MESSAGE_TYPES)) | ||
| 1269 | XD_SIGNAL2 (build_string ("Invalid message type"), message_type); | ||
| 1270 | |||
| 1271 | if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) | ||
| 1272 | || (mtype == DBUS_MESSAGE_TYPE_SIGNAL)) | ||
| 1273 | { | ||
| 1274 | path = args[3]; | ||
| 1275 | interface = args[4]; | ||
| 1276 | member = args[5]; | ||
| 1277 | if (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) | ||
| 1278 | handler = args[6]; | ||
| 1279 | count = (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) ? 7 : 6; | ||
| 1280 | } | ||
| 1281 | else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */ | ||
| 1282 | { | ||
| 1283 | XD_CHECK_DBUS_SERIAL (args[3], serial); | ||
| 1284 | count = 4; | ||
| 1285 | } | ||
| 1286 | |||
| 1113 | /* Check parameters. */ | 1287 | /* Check parameters. */ |
| 1114 | bus = args[0]; | 1288 | XD_DBUS_VALIDATE_BUS_ADDRESS (bus); |
| 1115 | service = args[1]; | 1289 | XD_DBUS_VALIDATE_BUS_NAME (service); |
| 1116 | path = args[2]; | 1290 | if (nargs < count) |
| 1117 | interface = args[3]; | 1291 | xsignal2 (Qwrong_number_of_arguments, |
| 1118 | method = args[4]; | 1292 | Qdbus_message_internal, |
| 1119 | 1293 | make_number (nargs)); | |
| 1120 | CHECK_STRING (service); | 1294 | |
| 1121 | CHECK_STRING (path); | 1295 | if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) |
| 1122 | CHECK_STRING (interface); | 1296 | || (mtype == DBUS_MESSAGE_TYPE_SIGNAL)) |
| 1123 | CHECK_STRING (method); | 1297 | { |
| 1124 | GCPRO5 (bus, service, path, interface, method); | 1298 | XD_DBUS_VALIDATE_PATH (path); |
| 1125 | 1299 | XD_DBUS_VALIDATE_INTERFACE (interface); | |
| 1126 | XD_DEBUG_MESSAGE ("%s %s %s %s", | 1300 | XD_DBUS_VALIDATE_MEMBER (member); |
| 1127 | SDATA (service), | 1301 | if (!NILP (handler) && (!FUNCTIONP (handler))) |
| 1128 | SDATA (path), | 1302 | wrong_type_argument (Qinvalid_function, handler); |
| 1129 | SDATA (interface), | 1303 | } |
| 1130 | SDATA (method)); | ||
| 1131 | |||
| 1132 | /* Open a connection to the bus. */ | ||
| 1133 | connection = xd_initialize (bus, TRUE); | ||
| 1134 | |||
| 1135 | /* Create the message. */ | ||
| 1136 | dmessage = dbus_message_new_method_call (SSDATA (service), | ||
| 1137 | SSDATA (path), | ||
| 1138 | SSDATA (interface), | ||
| 1139 | SSDATA (method)); | ||
| 1140 | UNGCPRO; | ||
| 1141 | if (dmessage == NULL) | ||
| 1142 | XD_SIGNAL1 (build_string ("Unable to create a new message")); | ||
| 1143 | 1304 | ||
| 1144 | /* Check for timeout parameter. */ | 1305 | /* Protect Lisp variables. */ |
| 1145 | if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout))) | 1306 | GCPRO6 (bus, service, path, interface, member, handler); |
| 1307 | |||
| 1308 | /* Trace parameters. */ | ||
| 1309 | switch (mtype) | ||
| 1146 | { | 1310 | { |
| 1147 | CHECK_NATNUM (args[i+1]); | 1311 | case DBUS_MESSAGE_TYPE_METHOD_CALL: |
| 1148 | timeout = min (XFASTINT (args[i+1]), INT_MAX); | 1312 | XD_DEBUG_MESSAGE ("%s %s %s %s %s %s %s", |
| 1149 | i = i+2; | 1313 | XD_MESSAGE_TYPE_TO_STRING (mtype), |
| 1314 | XD_OBJECT_TO_STRING (bus), | ||
| 1315 | XD_OBJECT_TO_STRING (service), | ||
| 1316 | XD_OBJECT_TO_STRING (path), | ||
| 1317 | XD_OBJECT_TO_STRING (interface), | ||
| 1318 | XD_OBJECT_TO_STRING (member), | ||
| 1319 | XD_OBJECT_TO_STRING (handler)); | ||
| 1320 | break; | ||
| 1321 | case DBUS_MESSAGE_TYPE_SIGNAL: | ||
| 1322 | XD_DEBUG_MESSAGE ("%s %s %s %s %s %s", | ||
| 1323 | XD_MESSAGE_TYPE_TO_STRING (mtype), | ||
| 1324 | XD_OBJECT_TO_STRING (bus), | ||
| 1325 | XD_OBJECT_TO_STRING (service), | ||
| 1326 | XD_OBJECT_TO_STRING (path), | ||
| 1327 | XD_OBJECT_TO_STRING (interface), | ||
| 1328 | XD_OBJECT_TO_STRING (member)); | ||
| 1329 | break; | ||
| 1330 | default: /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */ | ||
| 1331 | ui_serial = serial; | ||
| 1332 | XD_DEBUG_MESSAGE ("%s %s %s %u", | ||
| 1333 | XD_MESSAGE_TYPE_TO_STRING (mtype), | ||
| 1334 | XD_OBJECT_TO_STRING (bus), | ||
| 1335 | XD_OBJECT_TO_STRING (service), | ||
| 1336 | ui_serial); | ||
| 1150 | } | 1337 | } |
| 1151 | 1338 | ||
| 1152 | /* Initialize parameter list of message. */ | 1339 | /* Retrieve bus address. */ |
| 1153 | dbus_message_iter_init_append (dmessage, &iter); | 1340 | connection = xd_get_connection_address (bus); |
| 1154 | 1341 | ||
| 1155 | /* Append parameters to the message. */ | 1342 | /* Create the D-Bus message. */ |
| 1156 | for (; i < nargs; ++i) | 1343 | dmessage = dbus_message_new (mtype); |
| 1344 | if (dmessage == NULL) | ||
| 1157 | { | 1345 | { |
| 1158 | dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]); | 1346 | UNGCPRO; |
| 1159 | if (XD_DBUS_TYPE_P (args[i])) | 1347 | XD_SIGNAL1 (build_string ("Unable to create a new message")); |
| 1348 | } | ||
| 1349 | |||
| 1350 | if (STRINGP (service)) | ||
| 1351 | { | ||
| 1352 | if (mtype != DBUS_MESSAGE_TYPE_SIGNAL) | ||
| 1353 | /* Set destination. */ | ||
| 1160 | { | 1354 | { |
| 1161 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); | 1355 | if (!dbus_message_set_destination (dmessage, SSDATA (service))) |
| 1162 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]); | 1356 | { |
| 1163 | XD_DEBUG_MESSAGE ("Parameter%"pD"d %s %s", i - 4, | 1357 | UNGCPRO; |
| 1164 | SDATA (format2 ("%s", args[i], Qnil)), | 1358 | XD_SIGNAL2 (build_string ("Unable to set the destination"), |
| 1165 | SDATA (format2 ("%s", args[i+1], Qnil))); | 1359 | service); |
| 1166 | ++i; | 1360 | } |
| 1167 | } | 1361 | } |
| 1362 | |||
| 1168 | else | 1363 | else |
| 1364 | /* Set destination for unicast signals. */ | ||
| 1169 | { | 1365 | { |
| 1170 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); | 1366 | Lisp_Object uname; |
| 1171 | XD_DEBUG_MESSAGE ("Parameter%"pD"d %s", i - 4, | ||
| 1172 | SDATA (format2 ("%s", args[i], Qnil))); | ||
| 1173 | } | ||
| 1174 | 1367 | ||
| 1175 | /* Check for valid signature. We use DBUS_TYPE_INVALID as | 1368 | /* If it is the same unique name as we are registered at the |
| 1176 | indication that there is no parent type. */ | 1369 | bus or an unknown name, we regard it as broadcast message |
| 1177 | xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]); | 1370 | due to backward compatibility. */ |
| 1371 | if (dbus_bus_name_has_owner (connection, SSDATA (service), NULL)) | ||
| 1372 | uname = call2 (intern ("dbus-get-name-owner"), bus, service); | ||
| 1373 | else | ||
| 1374 | uname = Qnil; | ||
| 1178 | 1375 | ||
| 1179 | xd_append_arg (dtype, args[i], &iter); | 1376 | if (STRINGP (uname) |
| 1377 | && (strcmp (dbus_bus_get_unique_name (connection), SSDATA (uname)) | ||
| 1378 | != 0) | ||
| 1379 | && (!dbus_message_set_destination (dmessage, SSDATA (service)))) | ||
| 1380 | { | ||
| 1381 | UNGCPRO; | ||
| 1382 | XD_SIGNAL2 (build_string ("Unable to set signal destination"), | ||
| 1383 | service); | ||
| 1384 | } | ||
| 1385 | } | ||
| 1180 | } | 1386 | } |
| 1181 | 1387 | ||
| 1182 | /* Send the message. */ | 1388 | /* Set message parameters. */ |
| 1183 | dbus_error_init (&derror); | 1389 | if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) |
| 1184 | reply = dbus_connection_send_with_reply_and_block (connection, | 1390 | || (mtype == DBUS_MESSAGE_TYPE_SIGNAL)) |
| 1185 | dmessage, | ||
| 1186 | timeout, | ||
| 1187 | &derror); | ||
| 1188 | |||
| 1189 | if (dbus_error_is_set (&derror)) | ||
| 1190 | XD_ERROR (derror); | ||
| 1191 | |||
| 1192 | if (reply == NULL) | ||
| 1193 | XD_SIGNAL1 (build_string ("No reply")); | ||
| 1194 | |||
| 1195 | XD_DEBUG_MESSAGE ("Message sent"); | ||
| 1196 | |||
| 1197 | /* Collect the results. */ | ||
| 1198 | result = Qnil; | ||
| 1199 | GCPRO1 (result); | ||
| 1200 | |||
| 1201 | if (dbus_message_iter_init (reply, &iter)) | ||
| 1202 | { | 1391 | { |
| 1203 | /* Loop over the parameters of the D-Bus reply message. Construct a | 1392 | if ((!dbus_message_set_path (dmessage, SSDATA (path))) |
| 1204 | Lisp list, which is returned by `dbus-call-method'. */ | 1393 | || (!dbus_message_set_interface (dmessage, SSDATA (interface))) |
| 1205 | while ((dtype = dbus_message_iter_get_arg_type (&iter)) | 1394 | || (!dbus_message_set_member (dmessage, SSDATA (member)))) |
| 1206 | != DBUS_TYPE_INVALID) | ||
| 1207 | { | 1395 | { |
| 1208 | result = Fcons (xd_retrieve_arg (dtype, &iter), result); | 1396 | UNGCPRO; |
| 1209 | dbus_message_iter_next (&iter); | 1397 | XD_SIGNAL1 (build_string ("Unable to set the message parameter")); |
| 1210 | } | 1398 | } |
| 1211 | } | 1399 | } |
| 1212 | else | ||
| 1213 | { | ||
| 1214 | /* No arguments: just return nil. */ | ||
| 1215 | } | ||
| 1216 | |||
| 1217 | /* Cleanup. */ | ||
| 1218 | dbus_error_free (&derror); | ||
| 1219 | dbus_message_unref (dmessage); | ||
| 1220 | dbus_message_unref (reply); | ||
| 1221 | |||
| 1222 | /* Return the result. If there is only one single Lisp object, | ||
| 1223 | return it as-it-is, otherwise return the reversed list. */ | ||
| 1224 | if (XFASTINT (Flength (result)) == 1) | ||
| 1225 | RETURN_UNGCPRO (CAR_SAFE (result)); | ||
| 1226 | else | ||
| 1227 | RETURN_UNGCPRO (Fnreverse (result)); | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | DEFUN ("dbus-call-method-asynchronously", Fdbus_call_method_asynchronously, | ||
| 1231 | Sdbus_call_method_asynchronously, 6, MANY, 0, | ||
| 1232 | doc: /* Call METHOD on the D-Bus BUS asynchronously. | ||
| 1233 | |||
| 1234 | BUS is either a Lisp symbol, `:system' or `:session', or a string | ||
| 1235 | denoting the bus address. | ||
| 1236 | |||
| 1237 | SERVICE is the D-Bus service name to be used. PATH is the D-Bus | ||
| 1238 | object path SERVICE is registered at. INTERFACE is an interface | ||
| 1239 | offered by SERVICE. It must provide METHOD. | ||
| 1240 | |||
| 1241 | HANDLER is a Lisp function, which is called when the corresponding | ||
| 1242 | return message has arrived. If HANDLER is nil, no return message will | ||
| 1243 | be expected. | ||
| 1244 | |||
| 1245 | If the parameter `:timeout' is given, the following integer TIMEOUT | ||
| 1246 | specifies the maximum number of milliseconds the method call must | ||
| 1247 | return. The default value is 25,000. If the method call doesn't | ||
| 1248 | return in time, a D-Bus error is raised. | ||
| 1249 | |||
| 1250 | All other arguments ARGS are passed to METHOD as arguments. They are | ||
| 1251 | converted into D-Bus types via the following rules: | ||
| 1252 | |||
| 1253 | t and nil => DBUS_TYPE_BOOLEAN | ||
| 1254 | number => DBUS_TYPE_UINT32 | ||
| 1255 | integer => DBUS_TYPE_INT32 | ||
| 1256 | float => DBUS_TYPE_DOUBLE | ||
| 1257 | string => DBUS_TYPE_STRING | ||
| 1258 | list => DBUS_TYPE_ARRAY | ||
| 1259 | |||
| 1260 | All arguments can be preceded by a type symbol. For details about | ||
| 1261 | type symbols, see Info node `(dbus)Type Conversion'. | ||
| 1262 | 1400 | ||
| 1263 | Unless HANDLER is nil, the function returns a key into the hash table | 1401 | else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */ |
| 1264 | `dbus-registered-objects-table'. The corresponding entry in the hash | 1402 | { |
| 1265 | table is removed, when the return message has been arrived, and | 1403 | if (!dbus_message_set_reply_serial (dmessage, serial)) |
| 1266 | HANDLER is called. | 1404 | { |
| 1267 | 1405 | UNGCPRO; | |
| 1268 | Example: | 1406 | XD_SIGNAL1 (build_string ("Unable to create a return message")); |
| 1269 | 1407 | } | |
| 1270 | \(dbus-call-method-asynchronously | ||
| 1271 | :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer" | ||
| 1272 | "org.freedesktop.Hal.Device" "GetPropertyString" 'message | ||
| 1273 | "system.kernel.machine") | ||
| 1274 | |||
| 1275 | => (:system 2) | ||
| 1276 | |||
| 1277 | -| i686 | ||
| 1278 | |||
| 1279 | usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLER &optional :timeout TIMEOUT &rest ARGS) */) | ||
| 1280 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 1281 | { | ||
| 1282 | Lisp_Object bus, service, path, interface, method, handler; | ||
| 1283 | Lisp_Object result; | ||
| 1284 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; | ||
| 1285 | DBusConnection *connection; | ||
| 1286 | DBusMessage *dmessage; | ||
| 1287 | DBusMessageIter iter; | ||
| 1288 | unsigned int dtype; | ||
| 1289 | dbus_uint32_t serial; | ||
| 1290 | int timeout = -1; | ||
| 1291 | ptrdiff_t i = 6; | ||
| 1292 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; | ||
| 1293 | 1408 | ||
| 1294 | /* Check parameters. */ | 1409 | if ((mtype == DBUS_MESSAGE_TYPE_ERROR) |
| 1295 | bus = args[0]; | 1410 | && (!dbus_message_set_error_name (dmessage, DBUS_ERROR_FAILED))) |
| 1296 | service = args[1]; | 1411 | { |
| 1297 | path = args[2]; | 1412 | UNGCPRO; |
| 1298 | interface = args[3]; | 1413 | XD_SIGNAL1 (build_string ("Unable to create a error message")); |
| 1299 | method = args[4]; | 1414 | } |
| 1300 | handler = args[5]; | 1415 | } |
| 1301 | |||
| 1302 | CHECK_STRING (service); | ||
| 1303 | CHECK_STRING (path); | ||
| 1304 | CHECK_STRING (interface); | ||
| 1305 | CHECK_STRING (method); | ||
| 1306 | if (!NILP (handler) && !FUNCTIONP (handler)) | ||
| 1307 | wrong_type_argument (Qinvalid_function, handler); | ||
| 1308 | GCPRO6 (bus, service, path, interface, method, handler); | ||
| 1309 | |||
| 1310 | XD_DEBUG_MESSAGE ("%s %s %s %s", | ||
| 1311 | SDATA (service), | ||
| 1312 | SDATA (path), | ||
| 1313 | SDATA (interface), | ||
| 1314 | SDATA (method)); | ||
| 1315 | |||
| 1316 | /* Open a connection to the bus. */ | ||
| 1317 | connection = xd_initialize (bus, TRUE); | ||
| 1318 | |||
| 1319 | /* Create the message. */ | ||
| 1320 | dmessage = dbus_message_new_method_call (SSDATA (service), | ||
| 1321 | SSDATA (path), | ||
| 1322 | SSDATA (interface), | ||
| 1323 | SSDATA (method)); | ||
| 1324 | if (dmessage == NULL) | ||
| 1325 | XD_SIGNAL1 (build_string ("Unable to create a new message")); | ||
| 1326 | 1416 | ||
| 1327 | /* Check for timeout parameter. */ | 1417 | /* Check for timeout parameter. */ |
| 1328 | if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout))) | 1418 | if ((count+2 <= nargs) && (EQ ((args[count]), QCdbus_timeout))) |
| 1329 | { | 1419 | { |
| 1330 | CHECK_NATNUM (args[i+1]); | 1420 | CHECK_NATNUM (args[count+1]); |
| 1331 | timeout = min (XFASTINT (args[i+1]), INT_MAX); | 1421 | timeout = min (XFASTINT (args[count+1]), INT_MAX); |
| 1332 | i = i+2; | 1422 | count = count+2; |
| 1333 | } | 1423 | } |
| 1334 | 1424 | ||
| 1335 | /* Initialize parameter list of message. */ | 1425 | /* Initialize parameter list of message. */ |
| 1336 | dbus_message_iter_init_append (dmessage, &iter); | 1426 | dbus_message_iter_init_append (dmessage, &iter); |
| 1337 | 1427 | ||
| 1338 | /* Append parameters to the message. */ | 1428 | /* Append parameters to the message. */ |
| 1339 | for (; i < nargs; ++i) | 1429 | for (; count < nargs; ++count) |
| 1340 | { | 1430 | { |
| 1341 | dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]); | 1431 | dtype = XD_OBJECT_TO_DBUS_TYPE (args[count]); |
| 1342 | if (XD_DBUS_TYPE_P (args[i])) | 1432 | if (XD_DBUS_TYPE_P (args[count])) |
| 1343 | { | 1433 | { |
| 1344 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); | 1434 | XD_DEBUG_VALID_LISP_OBJECT_P (args[count]); |
| 1345 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]); | 1435 | XD_DEBUG_VALID_LISP_OBJECT_P (args[count+1]); |
| 1346 | XD_DEBUG_MESSAGE ("Parameter%"pD"d %s %s", i - 4, | 1436 | XD_DEBUG_MESSAGE ("Parameter%"pD"d %s %s", count - 4, |
| 1347 | SDATA (format2 ("%s", args[i], Qnil)), | 1437 | XD_OBJECT_TO_STRING (args[count]), |
| 1348 | SDATA (format2 ("%s", args[i+1], Qnil))); | 1438 | XD_OBJECT_TO_STRING (args[count+1])); |
| 1349 | ++i; | 1439 | ++count; |
| 1350 | } | 1440 | } |
| 1351 | else | 1441 | else |
| 1352 | { | 1442 | { |
| 1353 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); | 1443 | XD_DEBUG_VALID_LISP_OBJECT_P (args[count]); |
| 1354 | XD_DEBUG_MESSAGE ("Parameter%"pD"d %s", i - 4, | 1444 | XD_DEBUG_MESSAGE ("Parameter%"pD"d %s", count - 4, |
| 1355 | SDATA (format2 ("%s", args[i], Qnil))); | 1445 | XD_OBJECT_TO_STRING (args[count])); |
| 1356 | } | 1446 | } |
| 1357 | 1447 | ||
| 1358 | /* Check for valid signature. We use DBUS_TYPE_INVALID as | 1448 | /* Check for valid signature. We use DBUS_TYPE_INVALID as |
| 1359 | indication that there is no parent type. */ | 1449 | indication that there is no parent type. */ |
| 1360 | xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]); | 1450 | xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[count]); |
| 1361 | 1451 | ||
| 1362 | xd_append_arg (dtype, args[i], &iter); | 1452 | xd_append_arg (dtype, args[count], &iter); |
| 1363 | } | 1453 | } |
| 1364 | 1454 | ||
| 1365 | if (!NILP (handler)) | 1455 | if (!NILP (handler)) |
| @@ -1368,11 +1458,15 @@ usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLE | |||
| 1368 | message queue. */ | 1458 | message queue. */ |
| 1369 | if (!dbus_connection_send_with_reply (connection, dmessage, | 1459 | if (!dbus_connection_send_with_reply (connection, dmessage, |
| 1370 | NULL, timeout)) | 1460 | NULL, timeout)) |
| 1371 | XD_SIGNAL1 (build_string ("Cannot send message")); | 1461 | { |
| 1462 | UNGCPRO; | ||
| 1463 | XD_SIGNAL1 (build_string ("Cannot send message")); | ||
| 1464 | } | ||
| 1372 | 1465 | ||
| 1373 | /* The result is the key in Vdbus_registered_objects_table. */ | 1466 | /* The result is the key in Vdbus_registered_objects_table. */ |
| 1374 | serial = dbus_message_get_serial (dmessage); | 1467 | serial = dbus_message_get_serial (dmessage); |
| 1375 | result = list2 (bus, make_fixnum_or_float (serial)); | 1468 | result = list3 (QCdbus_registered_serial, |
| 1469 | bus, make_fixnum_or_float (serial)); | ||
| 1376 | 1470 | ||
| 1377 | /* Create a hash table entry. */ | 1471 | /* Create a hash table entry. */ |
| 1378 | Fputhash (result, handler, Vdbus_registered_objects_table); | 1472 | Fputhash (result, handler, Vdbus_registered_objects_table); |
| @@ -1382,12 +1476,15 @@ usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLE | |||
| 1382 | /* Send the message. The message is just added to the outgoing | 1476 | /* Send the message. The message is just added to the outgoing |
| 1383 | message queue. */ | 1477 | message queue. */ |
| 1384 | if (!dbus_connection_send (connection, dmessage, NULL)) | 1478 | if (!dbus_connection_send (connection, dmessage, NULL)) |
| 1385 | XD_SIGNAL1 (build_string ("Cannot send message")); | 1479 | { |
| 1480 | UNGCPRO; | ||
| 1481 | XD_SIGNAL1 (build_string ("Cannot send message")); | ||
| 1482 | } | ||
| 1386 | 1483 | ||
| 1387 | result = Qnil; | 1484 | result = Qnil; |
| 1388 | } | 1485 | } |
| 1389 | 1486 | ||
| 1390 | XD_DEBUG_MESSAGE ("Message sent"); | 1487 | XD_DEBUG_MESSAGE ("Message sent: %s", XD_OBJECT_TO_STRING (result)); |
| 1391 | 1488 | ||
| 1392 | /* Cleanup. */ | 1489 | /* Cleanup. */ |
| 1393 | dbus_message_unref (dmessage); | 1490 | dbus_message_unref (dmessage); |
| @@ -1396,300 +1493,6 @@ usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLE | |||
| 1396 | RETURN_UNGCPRO (result); | 1493 | RETURN_UNGCPRO (result); |
| 1397 | } | 1494 | } |
| 1398 | 1495 | ||
| 1399 | DEFUN ("dbus-method-return-internal", Fdbus_method_return_internal, | ||
| 1400 | Sdbus_method_return_internal, | ||
| 1401 | 3, MANY, 0, | ||
| 1402 | doc: /* Return for message SERIAL on the D-Bus BUS. | ||
| 1403 | This is an internal function, it shall not be used outside dbus.el. | ||
| 1404 | |||
| 1405 | usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */) | ||
| 1406 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 1407 | { | ||
| 1408 | Lisp_Object bus, service; | ||
| 1409 | struct gcpro gcpro1, gcpro2; | ||
| 1410 | DBusConnection *connection; | ||
| 1411 | DBusMessage *dmessage; | ||
| 1412 | DBusMessageIter iter; | ||
| 1413 | dbus_uint32_t serial; | ||
| 1414 | unsigned int ui_serial, dtype; | ||
| 1415 | ptrdiff_t i; | ||
| 1416 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; | ||
| 1417 | |||
| 1418 | /* Check parameters. */ | ||
| 1419 | bus = args[0]; | ||
| 1420 | service = args[2]; | ||
| 1421 | |||
| 1422 | CHECK_DBUS_SERIAL_GET_SERIAL (args[1], serial); | ||
| 1423 | CHECK_STRING (service); | ||
| 1424 | GCPRO2 (bus, service); | ||
| 1425 | |||
| 1426 | ui_serial = serial; | ||
| 1427 | XD_DEBUG_MESSAGE ("%u %s ", ui_serial, SSDATA (service)); | ||
| 1428 | |||
| 1429 | /* Open a connection to the bus. */ | ||
| 1430 | connection = xd_initialize (bus, TRUE); | ||
| 1431 | |||
| 1432 | /* Create the message. */ | ||
| 1433 | dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN); | ||
| 1434 | if ((dmessage == NULL) | ||
| 1435 | || (!dbus_message_set_reply_serial (dmessage, serial)) | ||
| 1436 | || (!dbus_message_set_destination (dmessage, SSDATA (service)))) | ||
| 1437 | { | ||
| 1438 | UNGCPRO; | ||
| 1439 | XD_SIGNAL1 (build_string ("Unable to create a return message")); | ||
| 1440 | } | ||
| 1441 | |||
| 1442 | UNGCPRO; | ||
| 1443 | |||
| 1444 | /* Initialize parameter list of message. */ | ||
| 1445 | dbus_message_iter_init_append (dmessage, &iter); | ||
| 1446 | |||
| 1447 | /* Append parameters to the message. */ | ||
| 1448 | for (i = 3; i < nargs; ++i) | ||
| 1449 | { | ||
| 1450 | dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]); | ||
| 1451 | if (XD_DBUS_TYPE_P (args[i])) | ||
| 1452 | { | ||
| 1453 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); | ||
| 1454 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]); | ||
| 1455 | XD_DEBUG_MESSAGE ("Parameter%"pD"d %s %s", i - 2, | ||
| 1456 | SDATA (format2 ("%s", args[i], Qnil)), | ||
| 1457 | SDATA (format2 ("%s", args[i+1], Qnil))); | ||
| 1458 | ++i; | ||
| 1459 | } | ||
| 1460 | else | ||
| 1461 | { | ||
| 1462 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); | ||
| 1463 | XD_DEBUG_MESSAGE ("Parameter%"pD"d %s", i - 2, | ||
| 1464 | SDATA (format2 ("%s", args[i], Qnil))); | ||
| 1465 | } | ||
| 1466 | |||
| 1467 | /* Check for valid signature. We use DBUS_TYPE_INVALID as | ||
| 1468 | indication that there is no parent type. */ | ||
| 1469 | xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]); | ||
| 1470 | |||
| 1471 | xd_append_arg (dtype, args[i], &iter); | ||
| 1472 | } | ||
| 1473 | |||
| 1474 | /* Send the message. The message is just added to the outgoing | ||
| 1475 | message queue. */ | ||
| 1476 | if (!dbus_connection_send (connection, dmessage, NULL)) | ||
| 1477 | XD_SIGNAL1 (build_string ("Cannot send message")); | ||
| 1478 | |||
| 1479 | XD_DEBUG_MESSAGE ("Message sent"); | ||
| 1480 | |||
| 1481 | /* Cleanup. */ | ||
| 1482 | dbus_message_unref (dmessage); | ||
| 1483 | |||
| 1484 | /* Return. */ | ||
| 1485 | return Qt; | ||
| 1486 | } | ||
| 1487 | |||
| 1488 | DEFUN ("dbus-method-error-internal", Fdbus_method_error_internal, | ||
| 1489 | Sdbus_method_error_internal, | ||
| 1490 | 3, MANY, 0, | ||
| 1491 | doc: /* Return error message for message SERIAL on the D-Bus BUS. | ||
| 1492 | This is an internal function, it shall not be used outside dbus.el. | ||
| 1493 | |||
| 1494 | usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */) | ||
| 1495 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 1496 | { | ||
| 1497 | Lisp_Object bus, service; | ||
| 1498 | struct gcpro gcpro1, gcpro2; | ||
| 1499 | DBusConnection *connection; | ||
| 1500 | DBusMessage *dmessage; | ||
| 1501 | DBusMessageIter iter; | ||
| 1502 | dbus_uint32_t serial; | ||
| 1503 | unsigned int ui_serial, dtype; | ||
| 1504 | ptrdiff_t i; | ||
| 1505 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; | ||
| 1506 | |||
| 1507 | /* Check parameters. */ | ||
| 1508 | bus = args[0]; | ||
| 1509 | service = args[2]; | ||
| 1510 | |||
| 1511 | CHECK_DBUS_SERIAL_GET_SERIAL (args[1], serial); | ||
| 1512 | CHECK_STRING (service); | ||
| 1513 | GCPRO2 (bus, service); | ||
| 1514 | |||
| 1515 | ui_serial = serial; | ||
| 1516 | XD_DEBUG_MESSAGE ("%u %s ", ui_serial, SSDATA (service)); | ||
| 1517 | |||
| 1518 | /* Open a connection to the bus. */ | ||
| 1519 | connection = xd_initialize (bus, TRUE); | ||
| 1520 | |||
| 1521 | /* Create the message. */ | ||
| 1522 | dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR); | ||
| 1523 | if ((dmessage == NULL) | ||
| 1524 | || (!dbus_message_set_error_name (dmessage, DBUS_ERROR_FAILED)) | ||
| 1525 | || (!dbus_message_set_reply_serial (dmessage, serial)) | ||
| 1526 | || (!dbus_message_set_destination (dmessage, SSDATA (service)))) | ||
| 1527 | { | ||
| 1528 | UNGCPRO; | ||
| 1529 | XD_SIGNAL1 (build_string ("Unable to create a error message")); | ||
| 1530 | } | ||
| 1531 | |||
| 1532 | UNGCPRO; | ||
| 1533 | |||
| 1534 | /* Initialize parameter list of message. */ | ||
| 1535 | dbus_message_iter_init_append (dmessage, &iter); | ||
| 1536 | |||
| 1537 | /* Append parameters to the message. */ | ||
| 1538 | for (i = 3; i < nargs; ++i) | ||
| 1539 | { | ||
| 1540 | dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]); | ||
| 1541 | if (XD_DBUS_TYPE_P (args[i])) | ||
| 1542 | { | ||
| 1543 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); | ||
| 1544 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]); | ||
| 1545 | XD_DEBUG_MESSAGE ("Parameter%"pD"d %s %s", i - 2, | ||
| 1546 | SDATA (format2 ("%s", args[i], Qnil)), | ||
| 1547 | SDATA (format2 ("%s", args[i+1], Qnil))); | ||
| 1548 | ++i; | ||
| 1549 | } | ||
| 1550 | else | ||
| 1551 | { | ||
| 1552 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); | ||
| 1553 | XD_DEBUG_MESSAGE ("Parameter%"pD"d %s", i - 2, | ||
| 1554 | SDATA (format2 ("%s", args[i], Qnil))); | ||
| 1555 | } | ||
| 1556 | |||
| 1557 | /* Check for valid signature. We use DBUS_TYPE_INVALID as | ||
| 1558 | indication that there is no parent type. */ | ||
| 1559 | xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]); | ||
| 1560 | |||
| 1561 | xd_append_arg (dtype, args[i], &iter); | ||
| 1562 | } | ||
| 1563 | |||
| 1564 | /* Send the message. The message is just added to the outgoing | ||
| 1565 | message queue. */ | ||
| 1566 | if (!dbus_connection_send (connection, dmessage, NULL)) | ||
| 1567 | XD_SIGNAL1 (build_string ("Cannot send message")); | ||
| 1568 | |||
| 1569 | XD_DEBUG_MESSAGE ("Message sent"); | ||
| 1570 | |||
| 1571 | /* Cleanup. */ | ||
| 1572 | dbus_message_unref (dmessage); | ||
| 1573 | |||
| 1574 | /* Return. */ | ||
| 1575 | return Qt; | ||
| 1576 | } | ||
| 1577 | |||
| 1578 | DEFUN ("dbus-send-signal", Fdbus_send_signal, Sdbus_send_signal, 5, MANY, 0, | ||
| 1579 | doc: /* Send signal SIGNAL on the D-Bus BUS. | ||
| 1580 | |||
| 1581 | BUS is either a Lisp symbol, `:system' or `:session', or a string | ||
| 1582 | denoting the bus address. | ||
| 1583 | |||
| 1584 | SERVICE is the D-Bus service name SIGNAL is sent from. PATH is the | ||
| 1585 | D-Bus object path SERVICE is registered at. INTERFACE is an interface | ||
| 1586 | offered by SERVICE. It must provide signal SIGNAL. | ||
| 1587 | |||
| 1588 | All other arguments ARGS are passed to SIGNAL as arguments. They are | ||
| 1589 | converted into D-Bus types via the following rules: | ||
| 1590 | |||
| 1591 | t and nil => DBUS_TYPE_BOOLEAN | ||
| 1592 | number => DBUS_TYPE_UINT32 | ||
| 1593 | integer => DBUS_TYPE_INT32 | ||
| 1594 | float => DBUS_TYPE_DOUBLE | ||
| 1595 | string => DBUS_TYPE_STRING | ||
| 1596 | list => DBUS_TYPE_ARRAY | ||
| 1597 | |||
| 1598 | All arguments can be preceded by a type symbol. For details about | ||
| 1599 | type symbols, see Info node `(dbus)Type Conversion'. | ||
| 1600 | |||
| 1601 | Example: | ||
| 1602 | |||
| 1603 | \(dbus-send-signal | ||
| 1604 | :session "org.gnu.Emacs" "/org/gnu/Emacs" | ||
| 1605 | "org.gnu.Emacs.FileManager" "FileModified" "/home/albinus/.emacs") | ||
| 1606 | |||
| 1607 | usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */) | ||
| 1608 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 1609 | { | ||
| 1610 | Lisp_Object bus, service, path, interface, signal; | ||
| 1611 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | ||
| 1612 | DBusConnection *connection; | ||
| 1613 | DBusMessage *dmessage; | ||
| 1614 | DBusMessageIter iter; | ||
| 1615 | unsigned int dtype; | ||
| 1616 | ptrdiff_t i; | ||
| 1617 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; | ||
| 1618 | |||
| 1619 | /* Check parameters. */ | ||
| 1620 | bus = args[0]; | ||
| 1621 | service = args[1]; | ||
| 1622 | path = args[2]; | ||
| 1623 | interface = args[3]; | ||
| 1624 | signal = args[4]; | ||
| 1625 | |||
| 1626 | CHECK_STRING (service); | ||
| 1627 | CHECK_STRING (path); | ||
| 1628 | CHECK_STRING (interface); | ||
| 1629 | CHECK_STRING (signal); | ||
| 1630 | GCPRO5 (bus, service, path, interface, signal); | ||
| 1631 | |||
| 1632 | XD_DEBUG_MESSAGE ("%s %s %s %s", | ||
| 1633 | SDATA (service), | ||
| 1634 | SDATA (path), | ||
| 1635 | SDATA (interface), | ||
| 1636 | SDATA (signal)); | ||
| 1637 | |||
| 1638 | /* Open a connection to the bus. */ | ||
| 1639 | connection = xd_initialize (bus, TRUE); | ||
| 1640 | |||
| 1641 | /* Create the message. */ | ||
| 1642 | dmessage = dbus_message_new_signal (SSDATA (path), | ||
| 1643 | SSDATA (interface), | ||
| 1644 | SSDATA (signal)); | ||
| 1645 | UNGCPRO; | ||
| 1646 | if (dmessage == NULL) | ||
| 1647 | XD_SIGNAL1 (build_string ("Unable to create a new message")); | ||
| 1648 | |||
| 1649 | /* Initialize parameter list of message. */ | ||
| 1650 | dbus_message_iter_init_append (dmessage, &iter); | ||
| 1651 | |||
| 1652 | /* Append parameters to the message. */ | ||
| 1653 | for (i = 5; i < nargs; ++i) | ||
| 1654 | { | ||
| 1655 | dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]); | ||
| 1656 | if (XD_DBUS_TYPE_P (args[i])) | ||
| 1657 | { | ||
| 1658 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); | ||
| 1659 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]); | ||
| 1660 | XD_DEBUG_MESSAGE ("Parameter%"pD"d %s %s", i - 4, | ||
| 1661 | SDATA (format2 ("%s", args[i], Qnil)), | ||
| 1662 | SDATA (format2 ("%s", args[i+1], Qnil))); | ||
| 1663 | ++i; | ||
| 1664 | } | ||
| 1665 | else | ||
| 1666 | { | ||
| 1667 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); | ||
| 1668 | XD_DEBUG_MESSAGE ("Parameter%"pD"d %s", i - 4, | ||
| 1669 | SDATA (format2 ("%s", args[i], Qnil))); | ||
| 1670 | } | ||
| 1671 | |||
| 1672 | /* Check for valid signature. We use DBUS_TYPE_INVALID as | ||
| 1673 | indication that there is no parent type. */ | ||
| 1674 | xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]); | ||
| 1675 | |||
| 1676 | xd_append_arg (dtype, args[i], &iter); | ||
| 1677 | } | ||
| 1678 | |||
| 1679 | /* Send the message. The message is just added to the outgoing | ||
| 1680 | message queue. */ | ||
| 1681 | if (!dbus_connection_send (connection, dmessage, NULL)) | ||
| 1682 | XD_SIGNAL1 (build_string ("Cannot send message")); | ||
| 1683 | |||
| 1684 | XD_DEBUG_MESSAGE ("Signal sent"); | ||
| 1685 | |||
| 1686 | /* Cleanup. */ | ||
| 1687 | dbus_message_unref (dmessage); | ||
| 1688 | |||
| 1689 | /* Return. */ | ||
| 1690 | return Qt; | ||
| 1691 | } | ||
| 1692 | |||
| 1693 | /* Read one queued incoming message of the D-Bus BUS. | 1496 | /* Read one queued incoming message of the D-Bus BUS. |
| 1694 | BUS is either a Lisp symbol, :system or :session, or a string denoting | 1497 | BUS is either a Lisp symbol, :system or :session, or a string denoting |
| 1695 | the bus address. */ | 1498 | the bus address. */ |
| @@ -1702,7 +1505,7 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1702 | DBusMessage *dmessage; | 1505 | DBusMessage *dmessage; |
| 1703 | DBusMessageIter iter; | 1506 | DBusMessageIter iter; |
| 1704 | unsigned int dtype; | 1507 | unsigned int dtype; |
| 1705 | int mtype; | 1508 | unsigned int mtype; |
| 1706 | dbus_uint32_t serial; | 1509 | dbus_uint32_t serial; |
| 1707 | unsigned int ui_serial; | 1510 | unsigned int ui_serial; |
| 1708 | const char *uname, *path, *interface, *member; | 1511 | const char *uname, *path, *interface, *member; |
| @@ -1744,23 +1547,19 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1744 | member = dbus_message_get_member (dmessage); | 1547 | member = dbus_message_get_member (dmessage); |
| 1745 | 1548 | ||
| 1746 | XD_DEBUG_MESSAGE ("Event received: %s %u %s %s %s %s %s", | 1549 | XD_DEBUG_MESSAGE ("Event received: %s %u %s %s %s %s %s", |
| 1747 | (mtype == DBUS_MESSAGE_TYPE_INVALID) | 1550 | XD_MESSAGE_TYPE_TO_STRING (mtype), |
| 1748 | ? "DBUS_MESSAGE_TYPE_INVALID" | ||
| 1749 | : (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) | ||
| 1750 | ? "DBUS_MESSAGE_TYPE_METHOD_CALL" | ||
| 1751 | : (mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) | ||
| 1752 | ? "DBUS_MESSAGE_TYPE_METHOD_RETURN" | ||
| 1753 | : (mtype == DBUS_MESSAGE_TYPE_ERROR) | ||
| 1754 | ? "DBUS_MESSAGE_TYPE_ERROR" | ||
| 1755 | : "DBUS_MESSAGE_TYPE_SIGNAL", | ||
| 1756 | ui_serial, uname, path, interface, member, | 1551 | ui_serial, uname, path, interface, member, |
| 1757 | SDATA (format2 ("%s", args, Qnil))); | 1552 | XD_OBJECT_TO_STRING (args)); |
| 1553 | |||
| 1554 | if (mtype == DBUS_MESSAGE_TYPE_INVALID) | ||
| 1555 | goto cleanup; | ||
| 1758 | 1556 | ||
| 1759 | if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) | 1557 | else if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) |
| 1760 | || (mtype == DBUS_MESSAGE_TYPE_ERROR)) | 1558 | || (mtype == DBUS_MESSAGE_TYPE_ERROR)) |
| 1761 | { | 1559 | { |
| 1762 | /* Search for a registered function of the message. */ | 1560 | /* Search for a registered function of the message. */ |
| 1763 | key = list2 (bus, make_fixnum_or_float (serial)); | 1561 | key = list3 (QCdbus_registered_serial, bus, |
| 1562 | make_fixnum_or_float (serial)); | ||
| 1764 | value = Fgethash (key, Vdbus_registered_objects_table, Qnil); | 1563 | value = Fgethash (key, Vdbus_registered_objects_table, Qnil); |
| 1765 | 1564 | ||
| 1766 | /* There shall be exactly one entry. Construct an event. */ | 1565 | /* There shall be exactly one entry. Construct an event. */ |
| @@ -1777,7 +1576,7 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1777 | event.arg = Fcons (value, args); | 1576 | event.arg = Fcons (value, args); |
| 1778 | } | 1577 | } |
| 1779 | 1578 | ||
| 1780 | else /* (mtype != DBUS_MESSAGE_TYPE_METHOD_RETURN) */ | 1579 | else /* DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_SIGNAL. */ |
| 1781 | { | 1580 | { |
| 1782 | /* Vdbus_registered_objects_table requires non-nil interface and | 1581 | /* Vdbus_registered_objects_table requires non-nil interface and |
| 1783 | member. */ | 1582 | member. */ |
| @@ -1785,7 +1584,10 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1785 | goto cleanup; | 1584 | goto cleanup; |
| 1786 | 1585 | ||
| 1787 | /* Search for a registered function of the message. */ | 1586 | /* Search for a registered function of the message. */ |
| 1788 | key = list3 (bus, build_string (interface), build_string (member)); | 1587 | key = list4 ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) |
| 1588 | ? QCdbus_registered_method | ||
| 1589 | : QCdbus_registered_signal, | ||
| 1590 | bus, build_string (interface), build_string (member)); | ||
| 1789 | value = Fgethash (key, Vdbus_registered_objects_table, Qnil); | 1591 | value = Fgethash (key, Vdbus_registered_objects_table, Qnil); |
| 1790 | 1592 | ||
| 1791 | /* Loop over the registered functions. Construct an event. */ | 1593 | /* Loop over the registered functions. Construct an event. */ |
| @@ -1835,8 +1637,7 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1835 | /* Store it into the input event queue. */ | 1637 | /* Store it into the input event queue. */ |
| 1836 | kbd_buffer_store_event (&event); | 1638 | kbd_buffer_store_event (&event); |
| 1837 | 1639 | ||
| 1838 | XD_DEBUG_MESSAGE ("Event stored: %s", | 1640 | XD_DEBUG_MESSAGE ("Event stored: %s", XD_OBJECT_TO_STRING (event.arg)); |
| 1839 | SDATA (format2 ("%s", event.arg, Qnil))); | ||
| 1840 | 1641 | ||
| 1841 | /* Cleanup. */ | 1642 | /* Cleanup. */ |
| 1842 | cleanup: | 1643 | cleanup: |
| @@ -1851,8 +1652,8 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1851 | static Lisp_Object | 1652 | static Lisp_Object |
| 1852 | xd_read_message (Lisp_Object bus) | 1653 | xd_read_message (Lisp_Object bus) |
| 1853 | { | 1654 | { |
| 1854 | /* Open a connection to the bus. */ | 1655 | /* Retrieve bus address. */ |
| 1855 | DBusConnection *connection = xd_initialize (bus, TRUE); | 1656 | DBusConnection *connection = xd_get_connection_address (bus); |
| 1856 | 1657 | ||
| 1857 | /* Non blocking read of the next available message. */ | 1658 | /* Non blocking read of the next available message. */ |
| 1858 | dbus_connection_read_write (connection, 0); | 1659 | dbus_connection_read_write (connection, 0); |
| @@ -1867,16 +1668,18 @@ xd_read_message (Lisp_Object bus) | |||
| 1867 | static void | 1668 | static void |
| 1868 | xd_read_queued_messages (int fd, void *data, int for_read) | 1669 | xd_read_queued_messages (int fd, void *data, int for_read) |
| 1869 | { | 1670 | { |
| 1870 | Lisp_Object busp = Vdbus_registered_buses; | 1671 | Lisp_Object busp = xd_registered_buses; |
| 1871 | Lisp_Object bus = Qnil; | 1672 | Lisp_Object bus = Qnil; |
| 1673 | Lisp_Object key; | ||
| 1872 | 1674 | ||
| 1873 | /* Find bus related to fd. */ | 1675 | /* Find bus related to fd. */ |
| 1874 | if (data != NULL) | 1676 | if (data != NULL) |
| 1875 | while (!NILP (busp)) | 1677 | while (!NILP (busp)) |
| 1876 | { | 1678 | { |
| 1877 | if ((SYMBOLP (CAR_SAFE (busp)) && XSYMBOL (CAR_SAFE (busp)) == data) | 1679 | key = CAR_SAFE (CAR_SAFE (busp)); |
| 1878 | || (STRINGP (CAR_SAFE (busp)) && XSTRING (CAR_SAFE (busp)) == data)) | 1680 | if ((SYMBOLP (key) && XSYMBOL (key) == data) |
| 1879 | bus = CAR_SAFE (busp); | 1681 | || (STRINGP (key) && XSTRING (key) == data)) |
| 1682 | bus = key; | ||
| 1880 | busp = CDR_SAFE (busp); | 1683 | busp = CDR_SAFE (busp); |
| 1881 | } | 1684 | } |
| 1882 | 1685 | ||
| @@ -1889,327 +1692,6 @@ xd_read_queued_messages (int fd, void *data, int for_read) | |||
| 1889 | xd_in_read_queued_messages = 0; | 1692 | xd_in_read_queued_messages = 0; |
| 1890 | } | 1693 | } |
| 1891 | 1694 | ||
| 1892 | DEFUN ("dbus-register-service", Fdbus_register_service, Sdbus_register_service, | ||
| 1893 | 2, MANY, 0, | ||
| 1894 | doc: /* Register known name SERVICE on the D-Bus BUS. | ||
| 1895 | |||
| 1896 | BUS is either a Lisp symbol, `:system' or `:session', or a string | ||
| 1897 | denoting the bus address. | ||
| 1898 | |||
| 1899 | SERVICE is the D-Bus service name that should be registered. It must | ||
| 1900 | be a known name. | ||
| 1901 | |||
| 1902 | FLAGS are keywords, which control how the service name is registered. | ||
| 1903 | The following keywords are recognized: | ||
| 1904 | |||
| 1905 | `:allow-replacement': Allow another service to become the primary | ||
| 1906 | owner if requested. | ||
| 1907 | |||
| 1908 | `:replace-existing': Request to replace the current primary owner. | ||
| 1909 | |||
| 1910 | `:do-not-queue': If we can not become the primary owner do not place | ||
| 1911 | us in the queue. | ||
| 1912 | |||
| 1913 | The function returns a keyword, indicating the result of the | ||
| 1914 | operation. One of the following keywords is returned: | ||
| 1915 | |||
| 1916 | `:primary-owner': Service has become the primary owner of the | ||
| 1917 | requested name. | ||
| 1918 | |||
| 1919 | `:in-queue': Service could not become the primary owner and has been | ||
| 1920 | placed in the queue. | ||
| 1921 | |||
| 1922 | `:exists': Service is already in the queue. | ||
| 1923 | |||
| 1924 | `:already-owner': Service is already the primary owner. | ||
| 1925 | |||
| 1926 | Example: | ||
| 1927 | |||
| 1928 | \(dbus-register-service :session dbus-service-emacs) | ||
| 1929 | |||
| 1930 | => :primary-owner. | ||
| 1931 | |||
| 1932 | \(dbus-register-service | ||
| 1933 | :session "org.freedesktop.TextEditor" | ||
| 1934 | dbus-service-allow-replacement dbus-service-replace-existing) | ||
| 1935 | |||
| 1936 | => :already-owner. | ||
| 1937 | |||
| 1938 | usage: (dbus-register-service BUS SERVICE &rest FLAGS) */) | ||
| 1939 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 1940 | { | ||
| 1941 | Lisp_Object bus, service; | ||
| 1942 | DBusConnection *connection; | ||
| 1943 | ptrdiff_t i; | ||
| 1944 | unsigned int value; | ||
| 1945 | unsigned int flags = 0; | ||
| 1946 | int result; | ||
| 1947 | DBusError derror; | ||
| 1948 | |||
| 1949 | bus = args[0]; | ||
| 1950 | service = args[1]; | ||
| 1951 | |||
| 1952 | /* Check parameters. */ | ||
| 1953 | CHECK_STRING (service); | ||
| 1954 | |||
| 1955 | /* Process flags. */ | ||
| 1956 | for (i = 2; i < nargs; ++i) { | ||
| 1957 | value = ((EQ (args[i], QCdbus_request_name_replace_existing)) | ||
| 1958 | ? DBUS_NAME_FLAG_REPLACE_EXISTING | ||
| 1959 | : (EQ (args[i], QCdbus_request_name_allow_replacement)) | ||
| 1960 | ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT | ||
| 1961 | : (EQ (args[i], QCdbus_request_name_do_not_queue)) | ||
| 1962 | ? DBUS_NAME_FLAG_DO_NOT_QUEUE | ||
| 1963 | : -1); | ||
| 1964 | if (value == -1) | ||
| 1965 | XD_SIGNAL2 (build_string ("Unrecognized name request flag"), args[i]); | ||
| 1966 | flags |= value; | ||
| 1967 | } | ||
| 1968 | |||
| 1969 | /* Open a connection to the bus. */ | ||
| 1970 | connection = xd_initialize (bus, TRUE); | ||
| 1971 | |||
| 1972 | /* Request the known name from the bus. */ | ||
| 1973 | dbus_error_init (&derror); | ||
| 1974 | result = dbus_bus_request_name (connection, SSDATA (service), flags, | ||
| 1975 | &derror); | ||
| 1976 | if (dbus_error_is_set (&derror)) | ||
| 1977 | XD_ERROR (derror); | ||
| 1978 | |||
| 1979 | /* Cleanup. */ | ||
| 1980 | dbus_error_free (&derror); | ||
| 1981 | |||
| 1982 | /* Return object. */ | ||
| 1983 | switch (result) | ||
| 1984 | { | ||
| 1985 | case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER: | ||
| 1986 | return QCdbus_request_name_reply_primary_owner; | ||
| 1987 | case DBUS_REQUEST_NAME_REPLY_IN_QUEUE: | ||
| 1988 | return QCdbus_request_name_reply_in_queue; | ||
| 1989 | case DBUS_REQUEST_NAME_REPLY_EXISTS: | ||
| 1990 | return QCdbus_request_name_reply_exists; | ||
| 1991 | case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER: | ||
| 1992 | return QCdbus_request_name_reply_already_owner; | ||
| 1993 | default: | ||
| 1994 | /* This should not happen. */ | ||
| 1995 | XD_SIGNAL2 (build_string ("Could not register service"), service); | ||
| 1996 | } | ||
| 1997 | } | ||
| 1998 | |||
| 1999 | DEFUN ("dbus-register-signal", Fdbus_register_signal, Sdbus_register_signal, | ||
| 2000 | 6, MANY, 0, | ||
| 2001 | doc: /* Register for signal SIGNAL on the D-Bus BUS. | ||
| 2002 | |||
| 2003 | BUS is either a Lisp symbol, `:system' or `:session', or a string | ||
| 2004 | denoting the bus address. | ||
| 2005 | |||
| 2006 | SERVICE is the D-Bus service name used by the sending D-Bus object. | ||
| 2007 | It can be either a known name or the unique name of the D-Bus object | ||
| 2008 | sending the signal. When SERVICE is nil, related signals from all | ||
| 2009 | D-Bus objects shall be accepted. | ||
| 2010 | |||
| 2011 | PATH is the D-Bus object path SERVICE is registered. It can also be | ||
| 2012 | nil if the path name of incoming signals shall not be checked. | ||
| 2013 | |||
| 2014 | INTERFACE is an interface offered by SERVICE. It must provide SIGNAL. | ||
| 2015 | HANDLER is a Lisp function to be called when the signal is received. | ||
| 2016 | It must accept as arguments the values SIGNAL is sending. | ||
| 2017 | |||
| 2018 | All other arguments ARGS, if specified, must be strings. They stand | ||
| 2019 | for the respective arguments of the signal in their order, and are | ||
| 2020 | used for filtering as well. A nil argument might be used to preserve | ||
| 2021 | the order. | ||
| 2022 | |||
| 2023 | INTERFACE, SIGNAL and HANDLER must not be nil. Example: | ||
| 2024 | |||
| 2025 | \(defun my-signal-handler (device) | ||
| 2026 | (message "Device %s added" device)) | ||
| 2027 | |||
| 2028 | \(dbus-register-signal | ||
| 2029 | :system "org.freedesktop.Hal" "/org/freedesktop/Hal/Manager" | ||
| 2030 | "org.freedesktop.Hal.Manager" "DeviceAdded" 'my-signal-handler) | ||
| 2031 | |||
| 2032 | => ((:system "org.freedesktop.Hal.Manager" "DeviceAdded") | ||
| 2033 | ("org.freedesktop.Hal" "/org/freedesktop/Hal/Manager" my-signal-handler)) | ||
| 2034 | |||
| 2035 | `dbus-register-signal' returns an object, which can be used in | ||
| 2036 | `dbus-unregister-object' for removing the registration. | ||
| 2037 | |||
| 2038 | usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARGS) */) | ||
| 2039 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 2040 | { | ||
| 2041 | Lisp_Object bus, service, path, interface, signal, handler; | ||
| 2042 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; | ||
| 2043 | Lisp_Object uname, key, key1, value; | ||
| 2044 | DBusConnection *connection; | ||
| 2045 | ptrdiff_t i; | ||
| 2046 | char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH]; | ||
| 2047 | int rulelen; | ||
| 2048 | DBusError derror; | ||
| 2049 | |||
| 2050 | /* Check parameters. */ | ||
| 2051 | bus = args[0]; | ||
| 2052 | service = args[1]; | ||
| 2053 | path = args[2]; | ||
| 2054 | interface = args[3]; | ||
| 2055 | signal = args[4]; | ||
| 2056 | handler = args[5]; | ||
| 2057 | |||
| 2058 | if (!NILP (service)) CHECK_STRING (service); | ||
| 2059 | if (!NILP (path)) CHECK_STRING (path); | ||
| 2060 | CHECK_STRING (interface); | ||
| 2061 | CHECK_STRING (signal); | ||
| 2062 | if (!FUNCTIONP (handler)) | ||
| 2063 | wrong_type_argument (Qinvalid_function, handler); | ||
| 2064 | GCPRO6 (bus, service, path, interface, signal, handler); | ||
| 2065 | |||
| 2066 | /* Retrieve unique name of service. If service is a known name, we | ||
| 2067 | will register for the corresponding unique name, if any. Signals | ||
| 2068 | are sent always with the unique name as sender. Note: the unique | ||
| 2069 | name of "org.freedesktop.DBus" is that string itself. */ | ||
| 2070 | if ((STRINGP (service)) | ||
| 2071 | && (SBYTES (service) > 0) | ||
| 2072 | && (strcmp (SSDATA (service), DBUS_SERVICE_DBUS) != 0) | ||
| 2073 | && (strncmp (SSDATA (service), ":", 1) != 0)) | ||
| 2074 | uname = call2 (intern ("dbus-get-name-owner"), bus, service); | ||
| 2075 | else | ||
| 2076 | uname = service; | ||
| 2077 | |||
| 2078 | /* Create a matching rule if the unique name exists (when no | ||
| 2079 | wildcard). */ | ||
| 2080 | if (NILP (uname) || (SBYTES (uname) > 0)) | ||
| 2081 | { | ||
| 2082 | /* Open a connection to the bus. */ | ||
| 2083 | connection = xd_initialize (bus, TRUE); | ||
| 2084 | |||
| 2085 | /* Create a rule to receive related signals. */ | ||
| 2086 | rulelen = snprintf (rule, sizeof rule, | ||
| 2087 | "type='signal',interface='%s',member='%s'", | ||
| 2088 | SDATA (interface), | ||
| 2089 | SDATA (signal)); | ||
| 2090 | if (! (0 <= rulelen && rulelen < sizeof rule)) | ||
| 2091 | string_overflow (); | ||
| 2092 | |||
| 2093 | /* Add unique name and path to the rule if they are non-nil. */ | ||
| 2094 | if (!NILP (uname)) | ||
| 2095 | { | ||
| 2096 | int len = snprintf (rule + rulelen, sizeof rule - rulelen, | ||
| 2097 | ",sender='%s'", SDATA (uname)); | ||
| 2098 | if (! (0 <= len && len < sizeof rule - rulelen)) | ||
| 2099 | string_overflow (); | ||
| 2100 | rulelen += len; | ||
| 2101 | } | ||
| 2102 | |||
| 2103 | if (!NILP (path)) | ||
| 2104 | { | ||
| 2105 | int len = snprintf (rule + rulelen, sizeof rule - rulelen, | ||
| 2106 | ",path='%s'", SDATA (path)); | ||
| 2107 | if (! (0 <= len && len < sizeof rule - rulelen)) | ||
| 2108 | string_overflow (); | ||
| 2109 | rulelen += len; | ||
| 2110 | } | ||
| 2111 | |||
| 2112 | /* Add arguments to the rule if they are non-nil. */ | ||
| 2113 | for (i = 6; i < nargs; ++i) | ||
| 2114 | if (!NILP (args[i])) | ||
| 2115 | { | ||
| 2116 | int len; | ||
| 2117 | CHECK_STRING (args[i]); | ||
| 2118 | len = snprintf (rule + rulelen, sizeof rule - rulelen, | ||
| 2119 | ",arg%"pD"d='%s'", i - 6, SDATA (args[i])); | ||
| 2120 | if (! (0 <= len && len < sizeof rule - rulelen)) | ||
| 2121 | string_overflow (); | ||
| 2122 | rulelen += len; | ||
| 2123 | } | ||
| 2124 | |||
| 2125 | /* Add the rule to the bus. */ | ||
| 2126 | dbus_error_init (&derror); | ||
| 2127 | dbus_bus_add_match (connection, rule, &derror); | ||
| 2128 | if (dbus_error_is_set (&derror)) | ||
| 2129 | { | ||
| 2130 | UNGCPRO; | ||
| 2131 | XD_ERROR (derror); | ||
| 2132 | } | ||
| 2133 | |||
| 2134 | /* Cleanup. */ | ||
| 2135 | dbus_error_free (&derror); | ||
| 2136 | |||
| 2137 | XD_DEBUG_MESSAGE ("Matching rule \"%s\" created", rule); | ||
| 2138 | } | ||
| 2139 | |||
| 2140 | /* Create a hash table entry. */ | ||
| 2141 | key = list3 (bus, interface, signal); | ||
| 2142 | key1 = list5 (uname, service, path, handler, build_string (rule)); | ||
| 2143 | value = Fgethash (key, Vdbus_registered_objects_table, Qnil); | ||
| 2144 | |||
| 2145 | if (NILP (Fmember (key1, value))) | ||
| 2146 | Fputhash (key, Fcons (key1, value), Vdbus_registered_objects_table); | ||
| 2147 | |||
| 2148 | /* Return object. */ | ||
| 2149 | RETURN_UNGCPRO (list2 (key, list3 (service, path, handler))); | ||
| 2150 | } | ||
| 2151 | |||
| 2152 | DEFUN ("dbus-register-method", Fdbus_register_method, Sdbus_register_method, | ||
| 2153 | 6, 7, 0, | ||
| 2154 | doc: /* Register for method METHOD on the D-Bus BUS. | ||
| 2155 | |||
| 2156 | BUS is either a Lisp symbol, `:system' or `:session', or a string | ||
| 2157 | denoting the bus address. | ||
| 2158 | |||
| 2159 | SERVICE is the D-Bus service name of the D-Bus object METHOD is | ||
| 2160 | registered for. It must be a known name (See discussion of | ||
| 2161 | DONT-REGISTER-SERVICE below). | ||
| 2162 | |||
| 2163 | PATH is the D-Bus object path SERVICE is registered (See discussion of | ||
| 2164 | DONT-REGISTER-SERVICE below). INTERFACE is the interface offered by | ||
| 2165 | SERVICE. It must provide METHOD. | ||
| 2166 | |||
| 2167 | HANDLER is a Lisp function to be called when a method call is | ||
| 2168 | received. It must accept the input arguments of METHOD. The return | ||
| 2169 | value of HANDLER is used for composing the returning D-Bus message. | ||
| 2170 | In case HANDLER shall return a reply message with an empty argument | ||
| 2171 | list, HANDLER must return the symbol `:ignore'. | ||
| 2172 | |||
| 2173 | When DONT-REGISTER-SERVICE is non-nil, the known name SERVICE is not | ||
| 2174 | registered. This means that other D-Bus clients have no way of | ||
| 2175 | noticing the newly registered method. When interfaces are constructed | ||
| 2176 | incrementally by adding single methods or properties at a time, | ||
| 2177 | DONT-REGISTER-SERVICE can be used to prevent other clients from | ||
| 2178 | discovering the still incomplete interface.*/) | ||
| 2179 | (Lisp_Object bus, Lisp_Object service, Lisp_Object path, | ||
| 2180 | Lisp_Object interface, Lisp_Object method, Lisp_Object handler, | ||
| 2181 | Lisp_Object dont_register_service) | ||
| 2182 | { | ||
| 2183 | Lisp_Object key, key1, value; | ||
| 2184 | Lisp_Object args[2] = { bus, service }; | ||
| 2185 | |||
| 2186 | /* Check parameters. */ | ||
| 2187 | CHECK_STRING (service); | ||
| 2188 | CHECK_STRING (path); | ||
| 2189 | CHECK_STRING (interface); | ||
| 2190 | CHECK_STRING (method); | ||
| 2191 | if (!FUNCTIONP (handler)) | ||
| 2192 | wrong_type_argument (Qinvalid_function, handler); | ||
| 2193 | /* TODO: We must check for a valid service name, otherwise there is | ||
| 2194 | a segmentation fault. */ | ||
| 2195 | |||
| 2196 | /* Request the name. */ | ||
| 2197 | if (NILP (dont_register_service)) | ||
| 2198 | Fdbus_register_service (2, args); | ||
| 2199 | |||
| 2200 | /* Create a hash table entry. We use nil for the unique name, | ||
| 2201 | because the method might be called from anybody. */ | ||
| 2202 | key = list3 (bus, interface, method); | ||
| 2203 | key1 = list4 (Qnil, service, path, handler); | ||
| 2204 | value = Fgethash (key, Vdbus_registered_objects_table, Qnil); | ||
| 2205 | |||
| 2206 | if (NILP (Fmember (key1, value))) | ||
| 2207 | Fputhash (key, Fcons (key1, value), Vdbus_registered_objects_table); | ||
| 2208 | |||
| 2209 | /* Return object. */ | ||
| 2210 | return list2 (key, list3 (service, path, handler)); | ||
| 2211 | } | ||
| 2212 | |||
| 2213 | 1695 | ||
| 2214 | void | 1696 | void |
| 2215 | syms_of_dbusbind (void) | 1697 | syms_of_dbusbind (void) |
| @@ -2218,35 +1700,11 @@ syms_of_dbusbind (void) | |||
| 2218 | DEFSYM (Qdbus_init_bus, "dbus-init-bus"); | 1700 | DEFSYM (Qdbus_init_bus, "dbus-init-bus"); |
| 2219 | defsubr (&Sdbus_init_bus); | 1701 | defsubr (&Sdbus_init_bus); |
| 2220 | 1702 | ||
| 2221 | DEFSYM (Qdbus_close_bus, "dbus-close-bus"); | ||
| 2222 | defsubr (&Sdbus_close_bus); | ||
| 2223 | |||
| 2224 | DEFSYM (Qdbus_get_unique_name, "dbus-get-unique-name"); | 1703 | DEFSYM (Qdbus_get_unique_name, "dbus-get-unique-name"); |
| 2225 | defsubr (&Sdbus_get_unique_name); | 1704 | defsubr (&Sdbus_get_unique_name); |
| 2226 | 1705 | ||
| 2227 | DEFSYM (Qdbus_call_method, "dbus-call-method"); | 1706 | DEFSYM (Qdbus_message_internal, "dbus-message-internal"); |
| 2228 | defsubr (&Sdbus_call_method); | 1707 | defsubr (&Sdbus_message_internal); |
| 2229 | |||
| 2230 | DEFSYM (Qdbus_call_method_asynchronously, "dbus-call-method-asynchronously"); | ||
| 2231 | defsubr (&Sdbus_call_method_asynchronously); | ||
| 2232 | |||
| 2233 | DEFSYM (Qdbus_method_return_internal, "dbus-method-return-internal"); | ||
| 2234 | defsubr (&Sdbus_method_return_internal); | ||
| 2235 | |||
| 2236 | DEFSYM (Qdbus_method_error_internal, "dbus-method-error-internal"); | ||
| 2237 | defsubr (&Sdbus_method_error_internal); | ||
| 2238 | |||
| 2239 | DEFSYM (Qdbus_send_signal, "dbus-send-signal"); | ||
| 2240 | defsubr (&Sdbus_send_signal); | ||
| 2241 | |||
| 2242 | DEFSYM (Qdbus_register_service, "dbus-register-service"); | ||
| 2243 | defsubr (&Sdbus_register_service); | ||
| 2244 | |||
| 2245 | DEFSYM (Qdbus_register_signal, "dbus-register-signal"); | ||
| 2246 | defsubr (&Sdbus_register_signal); | ||
| 2247 | |||
| 2248 | DEFSYM (Qdbus_register_method, "dbus-register-method"); | ||
| 2249 | defsubr (&Sdbus_register_method); | ||
| 2250 | 1708 | ||
| 2251 | DEFSYM (Qdbus_error, "dbus-error"); | 1709 | DEFSYM (Qdbus_error, "dbus-error"); |
| 2252 | Fput (Qdbus_error, Qerror_conditions, | 1710 | Fput (Qdbus_error, Qerror_conditions, |
| @@ -2256,13 +1714,6 @@ syms_of_dbusbind (void) | |||
| 2256 | 1714 | ||
| 2257 | DEFSYM (QCdbus_system_bus, ":system"); | 1715 | DEFSYM (QCdbus_system_bus, ":system"); |
| 2258 | DEFSYM (QCdbus_session_bus, ":session"); | 1716 | DEFSYM (QCdbus_session_bus, ":session"); |
| 2259 | DEFSYM (QCdbus_request_name_allow_replacement, ":allow-replacement"); | ||
| 2260 | DEFSYM (QCdbus_request_name_replace_existing, ":replace-existing"); | ||
| 2261 | DEFSYM (QCdbus_request_name_do_not_queue, ":do-not-queue"); | ||
| 2262 | DEFSYM (QCdbus_request_name_reply_primary_owner, ":primary-owner"); | ||
| 2263 | DEFSYM (QCdbus_request_name_reply_exists, ":exists"); | ||
| 2264 | DEFSYM (QCdbus_request_name_reply_in_queue, ":in-queue"); | ||
| 2265 | DEFSYM (QCdbus_request_name_reply_already_owner, ":already-owner"); | ||
| 2266 | DEFSYM (QCdbus_timeout, ":timeout"); | 1717 | DEFSYM (QCdbus_timeout, ":timeout"); |
| 2267 | DEFSYM (QCdbus_type_byte, ":byte"); | 1718 | DEFSYM (QCdbus_type_byte, ":byte"); |
| 2268 | DEFSYM (QCdbus_type_boolean, ":boolean"); | 1719 | DEFSYM (QCdbus_type_boolean, ":boolean"); |
| @@ -2276,20 +1727,66 @@ syms_of_dbusbind (void) | |||
| 2276 | DEFSYM (QCdbus_type_string, ":string"); | 1727 | DEFSYM (QCdbus_type_string, ":string"); |
| 2277 | DEFSYM (QCdbus_type_object_path, ":object-path"); | 1728 | DEFSYM (QCdbus_type_object_path, ":object-path"); |
| 2278 | DEFSYM (QCdbus_type_signature, ":signature"); | 1729 | DEFSYM (QCdbus_type_signature, ":signature"); |
| 2279 | |||
| 2280 | #ifdef DBUS_TYPE_UNIX_FD | 1730 | #ifdef DBUS_TYPE_UNIX_FD |
| 2281 | DEFSYM (QCdbus_type_unix_fd, ":unix-fd"); | 1731 | DEFSYM (QCdbus_type_unix_fd, ":unix-fd"); |
| 2282 | #endif | 1732 | #endif |
| 2283 | |||
| 2284 | DEFSYM (QCdbus_type_array, ":array"); | 1733 | DEFSYM (QCdbus_type_array, ":array"); |
| 2285 | DEFSYM (QCdbus_type_variant, ":variant"); | 1734 | DEFSYM (QCdbus_type_variant, ":variant"); |
| 2286 | DEFSYM (QCdbus_type_struct, ":struct"); | 1735 | DEFSYM (QCdbus_type_struct, ":struct"); |
| 2287 | DEFSYM (QCdbus_type_dict_entry, ":dict-entry"); | 1736 | DEFSYM (QCdbus_type_dict_entry, ":dict-entry"); |
| 1737 | DEFSYM (QCdbus_registered_serial, ":serial"); | ||
| 1738 | DEFSYM (QCdbus_registered_method, ":method"); | ||
| 1739 | DEFSYM (QCdbus_registered_signal, ":signal"); | ||
| 1740 | |||
| 1741 | DEFVAR_LISP ("dbus-compiled-version", | ||
| 1742 | Vdbus_compiled_version, | ||
| 1743 | doc: /* The version of D-Bus Emacs is compiled against. */); | ||
| 1744 | #ifdef DBUS_VERSION_STRING | ||
| 1745 | Vdbus_compiled_version = make_pure_c_string (DBUS_VERSION_STRING); | ||
| 1746 | #else | ||
| 1747 | Vdbus_compiled_version = Qnil; | ||
| 1748 | #endif | ||
| 1749 | |||
| 1750 | DEFVAR_LISP ("dbus-runtime-version", | ||
| 1751 | Vdbus_runtime_version, | ||
| 1752 | doc: /* The version of D-Bus Emacs runs with. */); | ||
| 1753 | { | ||
| 1754 | #ifdef DBUS_VERSION | ||
| 1755 | int major, minor, micro; | ||
| 1756 | char s[1024]; | ||
| 1757 | dbus_get_version (&major, &minor, µ); | ||
| 1758 | snprintf (s, sizeof s, "%d.%d.%d", major, minor, micro); | ||
| 1759 | Vdbus_runtime_version = make_string (s, strlen (s)); | ||
| 1760 | #else | ||
| 1761 | Vdbus_runtime_version = Qnil; | ||
| 1762 | #endif | ||
| 1763 | } | ||
| 1764 | |||
| 1765 | DEFVAR_LISP ("dbus-message-type-invalid", | ||
| 1766 | Vdbus_message_type_invalid, | ||
| 1767 | doc: /* This value is never a valid message type. */); | ||
| 1768 | Vdbus_message_type_invalid = make_number (DBUS_MESSAGE_TYPE_INVALID); | ||
| 2288 | 1769 | ||
| 2289 | DEFVAR_LISP ("dbus-registered-buses", | 1770 | DEFVAR_LISP ("dbus-message-type-method-call", |
| 2290 | Vdbus_registered_buses, | 1771 | Vdbus_message_type_method_call, |
| 2291 | doc: /* List of D-Bus buses we are polling for messages. */); | 1772 | doc: /* Message type of a method call message. */); |
| 2292 | Vdbus_registered_buses = Qnil; | 1773 | Vdbus_message_type_method_call = make_number (DBUS_MESSAGE_TYPE_METHOD_CALL); |
| 1774 | |||
| 1775 | DEFVAR_LISP ("dbus-message-type-method-return", | ||
| 1776 | Vdbus_message_type_method_return, | ||
| 1777 | doc: /* Message type of a method return message. */); | ||
| 1778 | Vdbus_message_type_method_return | ||
| 1779 | = make_number (DBUS_MESSAGE_TYPE_METHOD_RETURN); | ||
| 1780 | |||
| 1781 | DEFVAR_LISP ("dbus-message-type-error", | ||
| 1782 | Vdbus_message_type_error, | ||
| 1783 | doc: /* Message type of an error reply message. */); | ||
| 1784 | Vdbus_message_type_error = make_number (DBUS_MESSAGE_TYPE_ERROR); | ||
| 1785 | |||
| 1786 | DEFVAR_LISP ("dbus-message-type-signal", | ||
| 1787 | Vdbus_message_type_signal, | ||
| 1788 | doc: /* Message type of a signal message. */); | ||
| 1789 | Vdbus_message_type_signal = make_number (DBUS_MESSAGE_TYPE_SIGNAL); | ||
| 2293 | 1790 | ||
| 2294 | DEFVAR_LISP ("dbus-registered-objects-table", | 1791 | DEFVAR_LISP ("dbus-registered-objects-table", |
| 2295 | Vdbus_registered_objects_table, | 1792 | Vdbus_registered_objects_table, |
| @@ -2299,27 +1796,28 @@ There are two different uses of the hash table: for accessing | |||
| 2299 | registered interfaces properties, targeted by signals or method calls, | 1796 | registered interfaces properties, targeted by signals or method calls, |
| 2300 | and for calling handlers in case of non-blocking method call returns. | 1797 | and for calling handlers in case of non-blocking method call returns. |
| 2301 | 1798 | ||
| 2302 | In the first case, the key in the hash table is the list (BUS | 1799 | In the first case, the key in the hash table is the list (TYPE BUS |
| 2303 | INTERFACE MEMBER). BUS is either a Lisp symbol, `:system' or | 1800 | INTERFACE MEMBER). TYPE is one of the Lisp symbols `:method', |
| 1801 | `:signal' or `:property'. BUS is either a Lisp symbol, `:system' or | ||
| 2304 | `:session', or a string denoting the bus address. INTERFACE is a | 1802 | `:session', or a string denoting the bus address. INTERFACE is a |
| 2305 | string which denotes a D-Bus interface, and MEMBER, also a string, is | 1803 | string which denotes a D-Bus interface, and MEMBER, also a string, is |
| 2306 | either a method, a signal or a property INTERFACE is offering. All | 1804 | either a method, a signal or a property INTERFACE is offering. All |
| 2307 | arguments but BUS must not be nil. | 1805 | arguments but BUS must not be nil. |
| 2308 | 1806 | ||
| 2309 | The value in the hash table is a list of quadruple lists | 1807 | The value in the hash table is a list of quadruple lists \((UNAME |
| 2310 | \((UNAME SERVICE PATH OBJECT) (UNAME SERVICE PATH OBJECT) ...). | 1808 | SERVICE PATH OBJECT [RULE]) ...). SERVICE is the service name as |
| 2311 | SERVICE is the service name as registered, UNAME is the corresponding | 1809 | registered, UNAME is the corresponding unique name. In case of |
| 2312 | unique name. In case of registered methods and properties, UNAME is | 1810 | registered methods and properties, UNAME is nil. PATH is the object |
| 2313 | nil. PATH is the object path of the sending object. All of them can | 1811 | path of the sending object. All of them can be nil, which means a |
| 2314 | be nil, which means a wildcard then. OBJECT is either the handler to | 1812 | wildcard then. OBJECT is either the handler to be called when a D-Bus |
| 2315 | be called when a D-Bus message, which matches the key criteria, | 1813 | message, which matches the key criteria, arrives (TYPE `:method' and |
| 2316 | arrives (methods and signals), or a cons cell containing the value of | 1814 | `:signal'), or a cons cell containing the value of the property (TYPE |
| 2317 | the property. | 1815 | `:property'). |
| 2318 | 1816 | ||
| 2319 | For signals, there is also a fifth element RULE, which keeps the match | 1817 | For entries of type `:signal', there is also a fifth element RULE, |
| 2320 | string the signal is registered with. | 1818 | which keeps the match string the signal is registered with. |
| 2321 | 1819 | ||
| 2322 | In the second case, the key in the hash table is the list (BUS | 1820 | In the second case, the key in the hash table is the list (:serial BUS |
| 2323 | SERIAL). BUS is either a Lisp symbol, `:system' or `:session', or a | 1821 | SERIAL). BUS is either a Lisp symbol, `:system' or `:session', or a |
| 2324 | string denoting the bus address. SERIAL is the serial number of the | 1822 | string denoting the bus address. SERIAL is the serial number of the |
| 2325 | non-blocking method call, a reply is expected. Both arguments must | 1823 | non-blocking method call, a reply is expected. Both arguments must |
| @@ -2343,6 +1841,10 @@ be called when the D-Bus reply message arrives. */); | |||
| 2343 | Vdbus_debug = Qnil; | 1841 | Vdbus_debug = Qnil; |
| 2344 | #endif | 1842 | #endif |
| 2345 | 1843 | ||
| 1844 | /* Initialize internal objects. */ | ||
| 1845 | xd_registered_buses = Qnil; | ||
| 1846 | staticpro (&xd_registered_buses); | ||
| 1847 | |||
| 2346 | Fprovide (intern_c_string ("dbusbind"), Qnil); | 1848 | Fprovide (intern_c_string ("dbusbind"), Qnil); |
| 2347 | 1849 | ||
| 2348 | } | 1850 | } |