diff options
Diffstat (limited to 'src/dbusbind.c')
| -rw-r--r-- | src/dbusbind.c | 322 |
1 files changed, 238 insertions, 84 deletions
diff --git a/src/dbusbind.c b/src/dbusbind.c index 57625d3876e..136cea9adb4 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Elisp bindings for D-Bus. | 1 | /* Elisp bindings for D-Bus. |
| 2 | Copyright (C) 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2008 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -33,6 +33,7 @@ Boston, MA 02110-1301, USA. */ | |||
| 33 | /* Subroutines. */ | 33 | /* Subroutines. */ |
| 34 | Lisp_Object Qdbus_get_unique_name; | 34 | Lisp_Object Qdbus_get_unique_name; |
| 35 | Lisp_Object Qdbus_call_method; | 35 | Lisp_Object Qdbus_call_method; |
| 36 | Lisp_Object Qdbus_method_return; | ||
| 36 | Lisp_Object Qdbus_send_signal; | 37 | Lisp_Object Qdbus_send_signal; |
| 37 | Lisp_Object Qdbus_register_signal; | 38 | Lisp_Object Qdbus_register_signal; |
| 38 | Lisp_Object Qdbus_register_method; | 39 | Lisp_Object Qdbus_register_method; |
| @@ -159,14 +160,14 @@ Lisp_Object Vdbus_debug; | |||
| 159 | : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \ | 160 | : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \ |
| 160 | : (STRINGP (object)) ? DBUS_TYPE_STRING \ | 161 | : (STRINGP (object)) ? DBUS_TYPE_STRING \ |
| 161 | : (XD_DBUS_TYPE_P (object)) ? XD_SYMBOL_TO_DBUS_TYPE (object) \ | 162 | : (XD_DBUS_TYPE_P (object)) ? XD_SYMBOL_TO_DBUS_TYPE (object) \ |
| 162 | : (CONSP (object)) ? ((XD_DBUS_TYPE_P (XCAR (object))) \ | 163 | : (CONSP (object)) ? ((XD_DBUS_TYPE_P (CAR_SAFE (object))) \ |
| 163 | ? XD_SYMBOL_TO_DBUS_TYPE (XCAR (object)) \ | 164 | ? XD_SYMBOL_TO_DBUS_TYPE (CAR_SAFE (object)) \ |
| 164 | : DBUS_TYPE_ARRAY) \ | 165 | : DBUS_TYPE_ARRAY) \ |
| 165 | : DBUS_TYPE_INVALID) | 166 | : DBUS_TYPE_INVALID) |
| 166 | 167 | ||
| 167 | /* Return a list pointer which does not have a Lisp symbol as car. */ | 168 | /* Return a list pointer which does not have a Lisp symbol as car. */ |
| 168 | #define XD_NEXT_VALUE(object) \ | 169 | #define XD_NEXT_VALUE(object) \ |
| 169 | ((XD_DBUS_TYPE_P (XCAR (object))) ? XCDR (object) : object) | 170 | ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object) |
| 170 | 171 | ||
| 171 | /* Compute SIGNATURE of OBJECT. It must have a form that it can be | 172 | /* Compute SIGNATURE of OBJECT. It must have a form that it can be |
| 172 | used in dbus_message_iter_open_container. DTYPE is the DBusType | 173 | used in dbus_message_iter_open_container. DTYPE is the DBusType |
| @@ -228,16 +229,36 @@ xd_signature(signature, dtype, parent_type, object) | |||
| 228 | the whole element's signature. */ | 229 | the whole element's signature. */ |
| 229 | CHECK_CONS (object); | 230 | CHECK_CONS (object); |
| 230 | 231 | ||
| 231 | if (EQ (QCdbus_type_array, XCAR (elt))) /* Type symbol is optional. */ | 232 | /* Type symbol is optional. */ |
| 233 | if (EQ (QCdbus_type_array, CAR_SAFE (elt))) | ||
| 232 | elt = XD_NEXT_VALUE (elt); | 234 | elt = XD_NEXT_VALUE (elt); |
| 233 | subtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (elt)); | 235 | |
| 234 | xd_signature (x, subtype, dtype, XCAR (XD_NEXT_VALUE (elt))); | 236 | /* If the array is empty, DBUS_TYPE_STRING is the default |
| 237 | element type. */ | ||
| 238 | if (NILP (elt)) | ||
| 239 | { | ||
| 240 | subtype = DBUS_TYPE_STRING; | ||
| 241 | strcpy (x, DBUS_TYPE_STRING_AS_STRING); | ||
| 242 | } | ||
| 243 | else | ||
| 244 | { | ||
| 245 | subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); | ||
| 246 | xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); | ||
| 247 | } | ||
| 248 | |||
| 249 | /* If the element type is DBUS_TYPE_SIGNATURE, and this is the | ||
| 250 | only element, the value of this element is used as he array's | ||
| 251 | element signature. */ | ||
| 252 | if ((subtype == DBUS_TYPE_SIGNATURE) | ||
| 253 | && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt))) | ||
| 254 | && NILP (CDR_SAFE (XD_NEXT_VALUE (elt)))) | ||
| 255 | strcpy (x, SDATA (CAR_SAFE (XD_NEXT_VALUE (elt)))); | ||
| 235 | 256 | ||
| 236 | while (!NILP (elt)) | 257 | while (!NILP (elt)) |
| 237 | { | 258 | { |
| 238 | if (subtype != XD_OBJECT_TO_DBUS_TYPE (XCAR (elt))) | 259 | if (subtype != XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt))) |
| 239 | wrong_type_argument (intern ("D-Bus"), XCAR (elt)); | 260 | wrong_type_argument (intern ("D-Bus"), CAR_SAFE (elt)); |
| 240 | elt = XCDR (XD_NEXT_VALUE (elt)); | 261 | elt = CDR_SAFE (XD_NEXT_VALUE (elt)); |
| 241 | } | 262 | } |
| 242 | 263 | ||
| 243 | sprintf (signature, "%c%s", dtype, x); | 264 | sprintf (signature, "%c%s", dtype, x); |
| @@ -248,12 +269,12 @@ xd_signature(signature, dtype, parent_type, object) | |||
| 248 | CHECK_CONS (object); | 269 | CHECK_CONS (object); |
| 249 | 270 | ||
| 250 | elt = XD_NEXT_VALUE (elt); | 271 | elt = XD_NEXT_VALUE (elt); |
| 251 | subtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (elt)); | 272 | subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); |
| 252 | xd_signature (x, subtype, dtype, XCAR (XD_NEXT_VALUE (elt))); | 273 | xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); |
| 253 | 274 | ||
| 254 | if (!NILP (XCDR (XD_NEXT_VALUE (elt)))) | 275 | if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt)))) |
| 255 | wrong_type_argument (intern ("D-Bus"), | 276 | wrong_type_argument (intern ("D-Bus"), |
| 256 | XCAR (XCDR (XD_NEXT_VALUE (elt)))); | 277 | CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt)))); |
| 257 | 278 | ||
| 258 | sprintf (signature, "%c", dtype); | 279 | sprintf (signature, "%c", dtype); |
| 259 | break; | 280 | break; |
| @@ -270,10 +291,10 @@ xd_signature(signature, dtype, parent_type, object) | |||
| 270 | sprintf (signature, "%c", DBUS_STRUCT_BEGIN_CHAR ); | 291 | sprintf (signature, "%c", DBUS_STRUCT_BEGIN_CHAR ); |
| 271 | while (!NILP (elt)) | 292 | while (!NILP (elt)) |
| 272 | { | 293 | { |
| 273 | subtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (elt)); | 294 | subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); |
| 274 | xd_signature (x, subtype, dtype, XCAR (XD_NEXT_VALUE (elt))); | 295 | xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); |
| 275 | strcat (signature, x); | 296 | strcat (signature, x); |
| 276 | elt = XCDR (XD_NEXT_VALUE (elt)); | 297 | elt = CDR_SAFE (XD_NEXT_VALUE (elt)); |
| 277 | } | 298 | } |
| 278 | sprintf (signature, "%s%c", signature, DBUS_STRUCT_END_CHAR); | 299 | sprintf (signature, "%s%c", signature, DBUS_STRUCT_END_CHAR); |
| 279 | break; | 300 | break; |
| @@ -294,22 +315,22 @@ xd_signature(signature, dtype, parent_type, object) | |||
| 294 | 315 | ||
| 295 | /* First element. */ | 316 | /* First element. */ |
| 296 | elt = XD_NEXT_VALUE (elt); | 317 | elt = XD_NEXT_VALUE (elt); |
| 297 | subtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (elt)); | 318 | subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); |
| 298 | xd_signature (x, subtype, dtype, XCAR (XD_NEXT_VALUE (elt))); | 319 | xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); |
| 299 | strcat (signature, x); | 320 | strcat (signature, x); |
| 300 | 321 | ||
| 301 | if (!XD_BASIC_DBUS_TYPE (subtype)) | 322 | if (!XD_BASIC_DBUS_TYPE (subtype)) |
| 302 | wrong_type_argument (intern ("D-Bus"), XCAR (XD_NEXT_VALUE (elt))); | 323 | wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt))); |
| 303 | 324 | ||
| 304 | /* Second element. */ | 325 | /* Second element. */ |
| 305 | elt = XCDR (XD_NEXT_VALUE (elt)); | 326 | elt = CDR_SAFE (XD_NEXT_VALUE (elt)); |
| 306 | subtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (elt)); | 327 | subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); |
| 307 | xd_signature (x, subtype, dtype, XCAR (XD_NEXT_VALUE (elt))); | 328 | xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); |
| 308 | strcat (signature, x); | 329 | strcat (signature, x); |
| 309 | 330 | ||
| 310 | if (!NILP (XCDR (XD_NEXT_VALUE (elt)))) | 331 | if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt)))) |
| 311 | wrong_type_argument (intern ("D-Bus"), | 332 | wrong_type_argument (intern ("D-Bus"), |
| 312 | XCAR (XCDR (XD_NEXT_VALUE (elt)))); | 333 | CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt)))); |
| 313 | 334 | ||
| 314 | /* Closing signature. */ | 335 | /* Closing signature. */ |
| 315 | sprintf (signature, "%s%c", signature, DBUS_DICT_ENTRY_END_CHAR); | 336 | sprintf (signature, "%s%c", signature, DBUS_DICT_ENTRY_END_CHAR); |
| @@ -341,7 +362,7 @@ xd_append_arg (dtype, object, iter) | |||
| 341 | { | 362 | { |
| 342 | case DBUS_TYPE_BYTE: | 363 | case DBUS_TYPE_BYTE: |
| 343 | { | 364 | { |
| 344 | unsigned int val = XUINT (object) & 0xFF; | 365 | unsigned char val = XUINT (object) & 0xFF; |
| 345 | XD_DEBUG_MESSAGE ("%c %d", dtype, val); | 366 | XD_DEBUG_MESSAGE ("%c %d", dtype, val); |
| 346 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) | 367 | if (!dbus_message_iter_append_basic (iter, dtype, &val)) |
| 347 | xsignal2 (Qdbus_error, | 368 | xsignal2 (Qdbus_error, |
| @@ -445,20 +466,54 @@ xd_append_arg (dtype, object, iter) | |||
| 445 | 466 | ||
| 446 | /* All compound types except array have a type symbol. For | 467 | /* All compound types except array have a type symbol. For |
| 447 | array, it is optional. Skip it. */ | 468 | array, it is optional. Skip it. */ |
| 448 | if (!XD_BASIC_DBUS_TYPE (XD_OBJECT_TO_DBUS_TYPE (XCAR (object)))) | 469 | if (!XD_BASIC_DBUS_TYPE (XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)))) |
| 449 | object = XD_NEXT_VALUE (object); | 470 | object = XD_NEXT_VALUE (object); |
| 450 | 471 | ||
| 451 | /* Open new subiteration. */ | 472 | /* Open new subiteration. */ |
| 452 | switch (dtype) | 473 | switch (dtype) |
| 453 | { | 474 | { |
| 454 | case DBUS_TYPE_ARRAY: | 475 | case DBUS_TYPE_ARRAY: |
| 476 | /* An array has only elements of the same type. So it is | ||
| 477 | sufficient to check the first element's signature | ||
| 478 | only. */ | ||
| 479 | |||
| 480 | if (NILP (object)) | ||
| 481 | /* If the array is empty, DBUS_TYPE_STRING is the default | ||
| 482 | element type. */ | ||
| 483 | strcpy (signature, DBUS_TYPE_STRING_AS_STRING); | ||
| 484 | |||
| 485 | else | ||
| 486 | /* If the element type is DBUS_TYPE_SIGNATURE, and this is | ||
| 487 | the only element, the value of this element is used as | ||
| 488 | the array's element signature. */ | ||
| 489 | if ((XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)) | ||
| 490 | == DBUS_TYPE_SIGNATURE) | ||
| 491 | && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object))) | ||
| 492 | && NILP (CDR_SAFE (XD_NEXT_VALUE (object)))) | ||
| 493 | { | ||
| 494 | strcpy (signature, SDATA (CAR_SAFE (XD_NEXT_VALUE (object)))); | ||
| 495 | object = CDR_SAFE (XD_NEXT_VALUE (object)); | ||
| 496 | } | ||
| 497 | |||
| 498 | else | ||
| 499 | xd_signature (signature, | ||
| 500 | XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)), | ||
| 501 | dtype, CAR_SAFE (XD_NEXT_VALUE (object))); | ||
| 502 | |||
| 503 | XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature, | ||
| 504 | SDATA (format2 ("%s", object, Qnil))); | ||
| 505 | if (!dbus_message_iter_open_container (iter, dtype, | ||
| 506 | signature, &subiter)) | ||
| 507 | xsignal3 (Qdbus_error, | ||
| 508 | build_string ("Cannot open container"), | ||
| 509 | make_number (dtype), build_string (signature)); | ||
| 510 | break; | ||
| 511 | |||
| 455 | case DBUS_TYPE_VARIANT: | 512 | case DBUS_TYPE_VARIANT: |
| 456 | /* A variant has just one element. An array has elements of | 513 | /* A variant has just one element. */ |
| 457 | the same type. Both have been checked already for | 514 | xd_signature (signature, XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)), |
| 458 | correct types, it is sufficient to retrieve just the | 515 | dtype, CAR_SAFE (XD_NEXT_VALUE (object))); |
| 459 | signature of the first element. */ | 516 | |
| 460 | xd_signature (signature, XD_OBJECT_TO_DBUS_TYPE (XCAR (object)), | ||
| 461 | dtype, XCAR (XD_NEXT_VALUE (object))); | ||
| 462 | XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature, | 517 | XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature, |
| 463 | SDATA (format2 ("%s", object, Qnil))); | 518 | SDATA (format2 ("%s", object, Qnil))); |
| 464 | if (!dbus_message_iter_open_container (iter, dtype, | 519 | if (!dbus_message_iter_open_container (iter, dtype, |
| @@ -483,12 +538,12 @@ xd_append_arg (dtype, object, iter) | |||
| 483 | /* Loop over list elements. */ | 538 | /* Loop over list elements. */ |
| 484 | while (!NILP (object)) | 539 | while (!NILP (object)) |
| 485 | { | 540 | { |
| 486 | dtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (object)); | 541 | dtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)); |
| 487 | object = XD_NEXT_VALUE (object); | 542 | object = XD_NEXT_VALUE (object); |
| 488 | 543 | ||
| 489 | xd_append_arg (dtype, XCAR (object), &subiter); | 544 | xd_append_arg (dtype, CAR_SAFE (object), &subiter); |
| 490 | 545 | ||
| 491 | object = XCDR (object); | 546 | object = CDR_SAFE (object); |
| 492 | } | 547 | } |
| 493 | 548 | ||
| 494 | /* Close the subiteration. */ | 549 | /* Close the subiteration. */ |
| @@ -591,6 +646,7 @@ xd_retrieve_arg (dtype, iter) | |||
| 591 | result = Fcons (xd_retrieve_arg (subtype, &subiter), result); | 646 | result = Fcons (xd_retrieve_arg (subtype, &subiter), result); |
| 592 | dbus_message_iter_next (&subiter); | 647 | dbus_message_iter_next (&subiter); |
| 593 | } | 648 | } |
| 649 | XD_DEBUG_MESSAGE ("%c %s", dtype, SDATA (format2 ("%s", result, Qnil))); | ||
| 594 | RETURN_UNGCPRO (Fnreverse (result)); | 650 | RETURN_UNGCPRO (Fnreverse (result)); |
| 595 | } | 651 | } |
| 596 | 652 | ||
| @@ -600,7 +656,6 @@ xd_retrieve_arg (dtype, iter) | |||
| 600 | } | 656 | } |
| 601 | } | 657 | } |
| 602 | 658 | ||
| 603 | |||
| 604 | /* Initialize D-Bus connection. BUS is a Lisp symbol, either :system | 659 | /* Initialize D-Bus connection. BUS is a Lisp symbol, either :system |
| 605 | or :session. It tells which D-Bus to be initialized. */ | 660 | or :session. It tells which D-Bus to be initialized. */ |
| 606 | DBusConnection * | 661 | DBusConnection * |
| @@ -635,7 +690,7 @@ xd_initialize (bus) | |||
| 635 | 690 | ||
| 636 | DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name, | 691 | DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name, |
| 637 | 1, 1, 0, | 692 | 1, 1, 0, |
| 638 | doc: /* Return the unique name of Emacs registered at D-Bus BUS as string. */) | 693 | doc: /* Return the unique name of Emacs registered at D-Bus BUS. */) |
| 639 | (bus) | 694 | (bus) |
| 640 | Lisp_Object bus; | 695 | Lisp_Object bus; |
| 641 | { | 696 | { |
| @@ -760,10 +815,10 @@ usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &rest ARGS) */) | |||
| 760 | connection = xd_initialize (bus); | 815 | connection = xd_initialize (bus); |
| 761 | 816 | ||
| 762 | /* Create the message. */ | 817 | /* Create the message. */ |
| 763 | dmessage = dbus_message_new_method_call ((char *) SDATA (service), | 818 | dmessage = dbus_message_new_method_call (SDATA (service), |
| 764 | (char *) SDATA (path), | 819 | SDATA (path), |
| 765 | (char *) SDATA (interface), | 820 | SDATA (interface), |
| 766 | (char *) SDATA (method)); | 821 | SDATA (method)); |
| 767 | if (dmessage == NULL) | 822 | if (dmessage == NULL) |
| 768 | { | 823 | { |
| 769 | UNGCPRO; | 824 | UNGCPRO; |
| @@ -787,7 +842,7 @@ usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &rest ARGS) */) | |||
| 787 | if (XD_DBUS_TYPE_P (args[i])) | 842 | if (XD_DBUS_TYPE_P (args[i])) |
| 788 | ++i; | 843 | ++i; |
| 789 | 844 | ||
| 790 | /* Check for valid signature. We use DBUS_TYPE_INVALID is | 845 | /* Check for valid signature. We use DBUS_TYPE_INVALID as |
| 791 | indication that there is no parent type. */ | 846 | indication that there is no parent type. */ |
| 792 | xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]); | 847 | xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]); |
| 793 | 848 | ||
| @@ -813,18 +868,19 @@ usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &rest ARGS) */) | |||
| 813 | result = Qnil; | 868 | result = Qnil; |
| 814 | GCPRO1 (result); | 869 | GCPRO1 (result); |
| 815 | 870 | ||
| 816 | if (!dbus_message_iter_init (reply, &iter)) | 871 | if (dbus_message_iter_init (reply, &iter)) |
| 817 | { | 872 | { |
| 818 | UNGCPRO; | 873 | /* Loop over the parameters of the D-Bus reply message. Construct a |
| 819 | xsignal1 (Qdbus_error, build_string ("Cannot read reply")); | 874 | Lisp list, which is returned by `dbus-call-method'. */ |
| 875 | while ((dtype = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) | ||
| 876 | { | ||
| 877 | result = Fcons (xd_retrieve_arg (dtype, &iter), result); | ||
| 878 | dbus_message_iter_next (&iter); | ||
| 879 | } | ||
| 820 | } | 880 | } |
| 821 | 881 | else | |
| 822 | /* Loop over the parameters of the D-Bus reply message. Construct a | ||
| 823 | Lisp list, which is returned by `dbus-call-method'. */ | ||
| 824 | while ((dtype = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) | ||
| 825 | { | 882 | { |
| 826 | result = Fcons (xd_retrieve_arg (dtype, &iter), result); | 883 | /* No arguments: just return nil. */ |
| 827 | dbus_message_iter_next (&iter); | ||
| 828 | } | 884 | } |
| 829 | 885 | ||
| 830 | /* Cleanup. */ | 886 | /* Cleanup. */ |
| @@ -834,11 +890,97 @@ usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &rest ARGS) */) | |||
| 834 | /* Return the result. If there is only one single Lisp object, | 890 | /* Return the result. If there is only one single Lisp object, |
| 835 | return it as-it-is, otherwise return the reversed list. */ | 891 | return it as-it-is, otherwise return the reversed list. */ |
| 836 | if (XUINT (Flength (result)) == 1) | 892 | if (XUINT (Flength (result)) == 1) |
| 837 | RETURN_UNGCPRO (XCAR (result)); | 893 | RETURN_UNGCPRO (CAR_SAFE (result)); |
| 838 | else | 894 | else |
| 839 | RETURN_UNGCPRO (Fnreverse (result)); | 895 | RETURN_UNGCPRO (Fnreverse (result)); |
| 840 | } | 896 | } |
| 841 | 897 | ||
| 898 | DEFUN ("dbus-method-return", Fdbus_method_return, Sdbus_method_return, | ||
| 899 | 3, MANY, 0, | ||
| 900 | doc: /* Return to method SERIAL on the D-Bus BUS. | ||
| 901 | This is an internal function, it shall not be used outside dbus.el. | ||
| 902 | |||
| 903 | usage: (dbus-method-return BUS SERIAL SERVICE &rest ARGS) */) | ||
| 904 | (nargs, args) | ||
| 905 | int nargs; | ||
| 906 | register Lisp_Object *args; | ||
| 907 | { | ||
| 908 | Lisp_Object bus, serial, service; | ||
| 909 | struct gcpro gcpro1, gcpro2, gcpro3; | ||
| 910 | DBusConnection *connection; | ||
| 911 | DBusMessage *dmessage; | ||
| 912 | DBusMessageIter iter; | ||
| 913 | unsigned int dtype; | ||
| 914 | int i; | ||
| 915 | char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; | ||
| 916 | |||
| 917 | /* Check parameters. */ | ||
| 918 | bus = args[0]; | ||
| 919 | serial = args[1]; | ||
| 920 | service = args[2]; | ||
| 921 | |||
| 922 | CHECK_SYMBOL (bus); | ||
| 923 | CHECK_NUMBER (serial); | ||
| 924 | CHECK_STRING (service); | ||
| 925 | GCPRO3 (bus, serial, service); | ||
| 926 | |||
| 927 | XD_DEBUG_MESSAGE ("%d %s ", XUINT (serial), SDATA (service)); | ||
| 928 | |||
| 929 | /* Open a connection to the bus. */ | ||
| 930 | connection = xd_initialize (bus); | ||
| 931 | |||
| 932 | /* Create the message. */ | ||
| 933 | dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN); | ||
| 934 | if ((dmessage == NULL) | ||
| 935 | || (!dbus_message_set_reply_serial (dmessage, XUINT (serial))) | ||
| 936 | || (!dbus_message_set_destination (dmessage, SDATA (service)))) | ||
| 937 | { | ||
| 938 | UNGCPRO; | ||
| 939 | xsignal1 (Qdbus_error, | ||
| 940 | build_string ("Unable to create a return message")); | ||
| 941 | } | ||
| 942 | |||
| 943 | UNGCPRO; | ||
| 944 | |||
| 945 | /* Initialize parameter list of message. */ | ||
| 946 | dbus_message_iter_init_append (dmessage, &iter); | ||
| 947 | |||
| 948 | /* Append parameters to the message. */ | ||
| 949 | for (i = 3; i < nargs; ++i) | ||
| 950 | { | ||
| 951 | |||
| 952 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); | ||
| 953 | XD_DEBUG_MESSAGE ("Parameter%d %s", | ||
| 954 | i-2, SDATA (format2 ("%s", args[i], Qnil))); | ||
| 955 | |||
| 956 | dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]); | ||
| 957 | if (XD_DBUS_TYPE_P (args[i])) | ||
| 958 | ++i; | ||
| 959 | |||
| 960 | /* Check for valid signature. We use DBUS_TYPE_INVALID as | ||
| 961 | indication that there is no parent type. */ | ||
| 962 | xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]); | ||
| 963 | |||
| 964 | xd_append_arg (dtype, args[i], &iter); | ||
| 965 | } | ||
| 966 | |||
| 967 | /* Send the message. The message is just added to the outgoing | ||
| 968 | message queue. */ | ||
| 969 | if (!dbus_connection_send (connection, dmessage, NULL)) | ||
| 970 | xsignal1 (Qdbus_error, build_string ("Cannot send message")); | ||
| 971 | |||
| 972 | /* Flush connection to ensure the message is handled. */ | ||
| 973 | dbus_connection_flush (connection); | ||
| 974 | |||
| 975 | XD_DEBUG_MESSAGE ("Message sent"); | ||
| 976 | |||
| 977 | /* Cleanup. */ | ||
| 978 | dbus_message_unref (dmessage); | ||
| 979 | |||
| 980 | /* Return. */ | ||
| 981 | return Qt; | ||
| 982 | } | ||
| 983 | |||
| 842 | DEFUN ("dbus-send-signal", Fdbus_send_signal, Sdbus_send_signal, 5, MANY, 0, | 984 | DEFUN ("dbus-send-signal", Fdbus_send_signal, Sdbus_send_signal, 5, MANY, 0, |
| 843 | doc: /* Send signal SIGNAL on the D-Bus BUS. | 985 | doc: /* Send signal SIGNAL on the D-Bus BUS. |
| 844 | 986 | ||
| @@ -905,9 +1047,9 @@ usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */) | |||
| 905 | connection = xd_initialize (bus); | 1047 | connection = xd_initialize (bus); |
| 906 | 1048 | ||
| 907 | /* Create the message. */ | 1049 | /* Create the message. */ |
| 908 | dmessage = dbus_message_new_signal ((char *) SDATA (path), | 1050 | dmessage = dbus_message_new_signal (SDATA (path), |
| 909 | (char *) SDATA (interface), | 1051 | SDATA (interface), |
| 910 | (char *) SDATA (signal)); | 1052 | SDATA (signal)); |
| 911 | if (dmessage == NULL) | 1053 | if (dmessage == NULL) |
| 912 | { | 1054 | { |
| 913 | UNGCPRO; | 1055 | UNGCPRO; |
| @@ -930,7 +1072,7 @@ usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */) | |||
| 930 | if (XD_DBUS_TYPE_P (args[i])) | 1072 | if (XD_DBUS_TYPE_P (args[i])) |
| 931 | ++i; | 1073 | ++i; |
| 932 | 1074 | ||
| 933 | /* Check for valid signature. We use DBUS_TYPE_INVALID is | 1075 | /* Check for valid signature. We use DBUS_TYPE_INVALID as |
| 934 | indication that there is no parent type. */ | 1076 | indication that there is no parent type. */ |
| 935 | xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]); | 1077 | xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]); |
| 936 | 1078 | ||
| @@ -1020,20 +1162,22 @@ xd_read_message (bus) | |||
| 1020 | /* Loop over the registered functions. Construct an event. */ | 1162 | /* Loop over the registered functions. Construct an event. */ |
| 1021 | while (!NILP (value)) | 1163 | while (!NILP (value)) |
| 1022 | { | 1164 | { |
| 1023 | key = XCAR (value); | 1165 | key = CAR_SAFE (value); |
| 1024 | /* key has the structure (UNAME SERVICE PATH HANDLER). */ | 1166 | /* key has the structure (UNAME SERVICE PATH HANDLER). */ |
| 1025 | if (((uname == NULL) | 1167 | if (((uname == NULL) |
| 1026 | || (NILP (XCAR (key))) | 1168 | || (NILP (CAR_SAFE (key))) |
| 1027 | || (strcmp (uname, SDATA (XCAR (key))) == 0)) | 1169 | || (strcmp (uname, SDATA (CAR_SAFE (key))) == 0)) |
| 1028 | && ((path == NULL) | 1170 | && ((path == NULL) |
| 1029 | || (NILP (XCAR (XCDR (XCDR (key))))) | 1171 | || (NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (key))))) |
| 1030 | || (strcmp (path, SDATA (XCAR (XCDR (XCDR (key))))) == 0)) | 1172 | || (strcmp (path, SDATA (CAR_SAFE (CDR_SAFE (CDR_SAFE (key))))) |
| 1031 | && (!NILP (XCAR (XCDR (XCDR (XCDR (key))))))) | 1173 | == 0)) |
| 1174 | && (!NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key))))))) | ||
| 1032 | { | 1175 | { |
| 1033 | EVENT_INIT (event); | 1176 | EVENT_INIT (event); |
| 1034 | event.kind = DBUS_EVENT; | 1177 | event.kind = DBUS_EVENT; |
| 1035 | event.frame_or_window = Qnil; | 1178 | event.frame_or_window = Qnil; |
| 1036 | event.arg = Fcons (XCAR (XCDR (XCDR (XCDR (key)))), args); | 1179 | event.arg = Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))), |
| 1180 | args); | ||
| 1037 | 1181 | ||
| 1038 | /* Add uname, path, interface and member to the event. */ | 1182 | /* Add uname, path, interface and member to the event. */ |
| 1039 | event.arg = Fcons ((member == NULL ? Qnil : build_string (member)), | 1183 | event.arg = Fcons ((member == NULL ? Qnil : build_string (member)), |
| @@ -1046,13 +1190,19 @@ xd_read_message (bus) | |||
| 1046 | event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)), | 1190 | event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)), |
| 1047 | event.arg); | 1191 | event.arg); |
| 1048 | 1192 | ||
| 1193 | /* Add the message serial if needed, or nil. */ | ||
| 1194 | event.arg = Fcons ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL | ||
| 1195 | ? make_number (dbus_message_get_serial (dmessage)) | ||
| 1196 | : Qnil), | ||
| 1197 | event.arg); | ||
| 1198 | |||
| 1049 | /* Add the bus symbol to the event. */ | 1199 | /* Add the bus symbol to the event. */ |
| 1050 | event.arg = Fcons (bus, event.arg); | 1200 | event.arg = Fcons (bus, event.arg); |
| 1051 | 1201 | ||
| 1052 | /* Store it into the input event queue. */ | 1202 | /* Store it into the input event queue. */ |
| 1053 | kbd_buffer_store_event (&event); | 1203 | kbd_buffer_store_event (&event); |
| 1054 | } | 1204 | } |
| 1055 | value = XCDR (value); | 1205 | value = CDR_SAFE (value); |
| 1056 | } | 1206 | } |
| 1057 | 1207 | ||
| 1058 | /* Cleanup. */ | 1208 | /* Cleanup. */ |
| @@ -1130,8 +1280,8 @@ SIGNAL and HANDLER must not be nil. Example: | |||
| 1130 | will register for the corresponding unique name, if any. Signals | 1280 | will register for the corresponding unique name, if any. Signals |
| 1131 | are sent always with the unique name as sender. Note: the unique | 1281 | are sent always with the unique name as sender. Note: the unique |
| 1132 | name of "org.freedesktop.DBus" is that string itself. */ | 1282 | name of "org.freedesktop.DBus" is that string itself. */ |
| 1133 | if ((!NILP (service)) | 1283 | if ((STRINGP (service)) |
| 1134 | && (strlen (SDATA (service)) > 0) | 1284 | && (SBYTES (service) > 0) |
| 1135 | && (strcmp (SDATA (service), DBUS_SERVICE_DBUS) != 0) | 1285 | && (strcmp (SDATA (service), DBUS_SERVICE_DBUS) != 0) |
| 1136 | && (strncmp (SDATA (service), ":", 1) != 0)) | 1286 | && (strncmp (SDATA (service), ":", 1) != 0)) |
| 1137 | { | 1287 | { |
| @@ -1146,7 +1296,7 @@ SIGNAL and HANDLER must not be nil. Example: | |||
| 1146 | 1296 | ||
| 1147 | /* Create a matching rule if the unique name exists (when no | 1297 | /* Create a matching rule if the unique name exists (when no |
| 1148 | wildcard). */ | 1298 | wildcard). */ |
| 1149 | if (NILP (uname) || (strlen (SDATA (uname)) > 0)) | 1299 | if (NILP (uname) || (SBYTES (uname) > 0)) |
| 1150 | { | 1300 | { |
| 1151 | /* Open a connection to the bus. */ | 1301 | /* Open a connection to the bus. */ |
| 1152 | connection = xd_initialize (bus); | 1302 | connection = xd_initialize (bus); |
| @@ -1198,9 +1348,7 @@ PATH is the D-Bus object path SERVICE is registered. INTERFACE is the | |||
| 1198 | interface offered by SERVICE. It must provide METHOD. HANDLER is a | 1348 | interface offered by SERVICE. It must provide METHOD. HANDLER is a |
| 1199 | Lisp function to be called when a method call is received. It must | 1349 | Lisp function to be called when a method call is received. It must |
| 1200 | accept the input arguments of METHOD. The return value of HANDLER is | 1350 | accept the input arguments of METHOD. The return value of HANDLER is |
| 1201 | used for composing the returning D-Bus message. | 1351 | used for composing the returning D-Bus message. */) |
| 1202 | |||
| 1203 | The function is not fully implemented and documented. Don't use it. */) | ||
| 1204 | (bus, service, path, interface, method, handler) | 1352 | (bus, service, path, interface, method, handler) |
| 1205 | Lisp_Object bus, service, path, interface, method, handler; | 1353 | Lisp_Object bus, service, path, interface, method, handler; |
| 1206 | { | 1354 | { |
| @@ -1209,9 +1357,6 @@ The function is not fully implemented and documented. Don't use it. */) | |||
| 1209 | int result; | 1357 | int result; |
| 1210 | DBusError derror; | 1358 | DBusError derror; |
| 1211 | 1359 | ||
| 1212 | if (NILP (Vdbus_debug)) | ||
| 1213 | xsignal1 (Qdbus_error, build_string ("Not implemented yet")); | ||
| 1214 | |||
| 1215 | /* Check parameters. */ | 1360 | /* Check parameters. */ |
| 1216 | CHECK_SYMBOL (bus); | 1361 | CHECK_SYMBOL (bus); |
| 1217 | CHECK_STRING (service); | 1362 | CHECK_STRING (service); |
| @@ -1247,7 +1392,8 @@ The function is not fully implemented and documented. Don't use it. */) | |||
| 1247 | return list2 (key, list3 (service, path, handler)); | 1392 | return list2 (key, list3 (service, path, handler)); |
| 1248 | } | 1393 | } |
| 1249 | 1394 | ||
| 1250 | DEFUN ("dbus-unregister-object", Fdbus_unregister_object, Sdbus_unregister_object, | 1395 | DEFUN ("dbus-unregister-object", Fdbus_unregister_object, |
| 1396 | Sdbus_unregister_object, | ||
| 1251 | 1, 1, 0, | 1397 | 1, 1, 0, |
| 1252 | doc: /* Unregister OBJECT from the D-Bus. | 1398 | doc: /* Unregister OBJECT from the D-Bus. |
| 1253 | OBJECT must be the result of a preceding `dbus-register-signal' or | 1399 | OBJECT must be the result of a preceding `dbus-register-signal' or |
| @@ -1260,11 +1406,12 @@ unregistered, nil otherwise. */) | |||
| 1260 | struct gcpro gcpro1; | 1406 | struct gcpro gcpro1; |
| 1261 | 1407 | ||
| 1262 | /* Check parameter. */ | 1408 | /* Check parameter. */ |
| 1263 | if (!(CONSP (object) && (!NILP (XCAR (object))) && CONSP (XCDR (object)))) | 1409 | if (!(CONSP (object) && (!NILP (CAR_SAFE (object))) |
| 1410 | && CONSP (CDR_SAFE (object)))) | ||
| 1264 | wrong_type_argument (intern ("D-Bus"), object); | 1411 | wrong_type_argument (intern ("D-Bus"), object); |
| 1265 | 1412 | ||
| 1266 | /* Find the corresponding entry in the hash table. */ | 1413 | /* Find the corresponding entry in the hash table. */ |
| 1267 | value = Fgethash (XCAR (object), Vdbus_registered_functions_table, Qnil); | 1414 | value = Fgethash (CAR_SAFE (object), Vdbus_registered_functions_table, Qnil); |
| 1268 | 1415 | ||
| 1269 | /* Loop over the registered functions. */ | 1416 | /* Loop over the registered functions. */ |
| 1270 | while (!NILP (value)) | 1417 | while (!NILP (value)) |
| @@ -1273,20 +1420,22 @@ unregistered, nil otherwise. */) | |||
| 1273 | 1420 | ||
| 1274 | /* (car value) has the structure (UNAME SERVICE PATH HANDLER). | 1421 | /* (car value) has the structure (UNAME SERVICE PATH HANDLER). |
| 1275 | (cdr object) has the structure ((SERVICE PATH HANDLER) ...). */ | 1422 | (cdr object) has the structure ((SERVICE PATH HANDLER) ...). */ |
| 1276 | if (!NILP (Fequal (XCDR (XCAR (value)), XCAR (XCDR (object))))) | 1423 | if (!NILP (Fequal (CDR_SAFE (CAR_SAFE (value)), |
| 1424 | CAR_SAFE (CDR_SAFE (object))))) | ||
| 1277 | { | 1425 | { |
| 1278 | /* Compute new hash value. */ | 1426 | /* Compute new hash value. */ |
| 1279 | value = Fdelete (XCAR (value), | 1427 | value = Fdelete (CAR_SAFE (value), |
| 1280 | Fgethash (XCAR (object), | 1428 | Fgethash (CAR_SAFE (object), |
| 1281 | Vdbus_registered_functions_table, Qnil)); | 1429 | Vdbus_registered_functions_table, Qnil)); |
| 1282 | if (NILP (value)) | 1430 | if (NILP (value)) |
| 1283 | Fremhash (XCAR (object), Vdbus_registered_functions_table); | 1431 | Fremhash (CAR_SAFE (object), Vdbus_registered_functions_table); |
| 1284 | else | 1432 | else |
| 1285 | Fputhash (XCAR (object), value, Vdbus_registered_functions_table); | 1433 | Fputhash (CAR_SAFE (object), value, |
| 1434 | Vdbus_registered_functions_table); | ||
| 1286 | RETURN_UNGCPRO (Qt); | 1435 | RETURN_UNGCPRO (Qt); |
| 1287 | } | 1436 | } |
| 1288 | UNGCPRO; | 1437 | UNGCPRO; |
| 1289 | value = XCDR (value); | 1438 | value = CDR_SAFE (value); |
| 1290 | } | 1439 | } |
| 1291 | 1440 | ||
| 1292 | /* Return. */ | 1441 | /* Return. */ |
| @@ -1306,6 +1455,10 @@ syms_of_dbusbind () | |||
| 1306 | staticpro (&Qdbus_call_method); | 1455 | staticpro (&Qdbus_call_method); |
| 1307 | defsubr (&Sdbus_call_method); | 1456 | defsubr (&Sdbus_call_method); |
| 1308 | 1457 | ||
| 1458 | Qdbus_method_return = intern ("dbus-method-return"); | ||
| 1459 | staticpro (&Qdbus_method_return); | ||
| 1460 | defsubr (&Sdbus_method_return); | ||
| 1461 | |||
| 1309 | Qdbus_send_signal = intern ("dbus-send-signal"); | 1462 | Qdbus_send_signal = intern ("dbus-send-signal"); |
| 1310 | staticpro (&Qdbus_send_signal); | 1463 | staticpro (&Qdbus_send_signal); |
| 1311 | defsubr (&Sdbus_send_signal); | 1464 | defsubr (&Sdbus_send_signal); |
| @@ -1383,7 +1536,8 @@ syms_of_dbusbind () | |||
| 1383 | QCdbus_type_dict_entry = intern (":dict-entry"); | 1536 | QCdbus_type_dict_entry = intern (":dict-entry"); |
| 1384 | staticpro (&QCdbus_type_dict_entry); | 1537 | staticpro (&QCdbus_type_dict_entry); |
| 1385 | 1538 | ||
| 1386 | DEFVAR_LISP ("dbus-registered-functions-table", &Vdbus_registered_functions_table, | 1539 | DEFVAR_LISP ("dbus-registered-functions-table", |
| 1540 | &Vdbus_registered_functions_table, | ||
| 1387 | doc: /* Hash table of registered functions for D-Bus. | 1541 | doc: /* Hash table of registered functions for D-Bus. |
| 1388 | The key in the hash table is the list (BUS INTERFACE MEMBER). BUS is | 1542 | The key in the hash table is the list (BUS INTERFACE MEMBER). BUS is |
| 1389 | either the symbol `:system' or the symbol `:session'. INTERFACE is a | 1543 | either the symbol `:system' or the symbol `:session'. INTERFACE is a |