aboutsummaryrefslogtreecommitdiffstats
path: root/src/dbusbind.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dbusbind.c')
-rw-r--r--src/dbusbind.c224
1 files changed, 129 insertions, 95 deletions
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 07fc24243d7..0ccccc8b22d 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -112,7 +112,7 @@ Lisp_Object Vdbus_debug;
112 message. */ 112 message. */
113char * 113char *
114xd_retrieve_value (dtype, object) 114xd_retrieve_value (dtype, object)
115 uint dtype; 115 unsigned int dtype;
116 Lisp_Object object; 116 Lisp_Object object;
117{ 117{
118 118
@@ -146,7 +146,7 @@ xd_retrieve_value (dtype, object)
146 partly supported; they result always in a Lisp list. */ 146 partly supported; they result always in a Lisp list. */
147Lisp_Object 147Lisp_Object
148xd_retrieve_arg (dtype, iter) 148xd_retrieve_arg (dtype, iter)
149 uint dtype; 149 unsigned int dtype;
150 DBusMessageIter *iter; 150 DBusMessageIter *iter;
151{ 151{
152 152
@@ -241,7 +241,7 @@ DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name,
241 Lisp_Object bus; 241 Lisp_Object bus;
242{ 242{
243 DBusConnection *connection; 243 DBusConnection *connection;
244 char name[1024]; 244 char name[DBUS_MAXIMUM_NAME_LENGTH];
245 245
246 /* Check parameters. */ 246 /* Check parameters. */
247 CHECK_SYMBOL (bus); 247 CHECK_SYMBOL (bus);
@@ -287,8 +287,8 @@ are converted into a list of Lisp objects which correspond to the
287elements of the D-Bus container. Example: 287elements of the D-Bus container. Example:
288 288
289\(dbus-call-method 289\(dbus-call-method
290 :session "GetKeyField" "org.gnome.seahorse" 290 :session "org.gnome.seahorse" "/org/gnome/seahorse/keys/openpgp"
291 "/org/gnome/seahorse/keys/openpgp" "org.gnome.seahorse.Keys" 291 "org.gnome.seahorse.Keys" "GetKeyField"
292 "openpgp:657984B8C7A966DD" "simple-name") 292 "openpgp:657984B8C7A966DD" "simple-name")
293 293
294 => (t ("Philip R. Zimmermann")) 294 => (t ("Philip R. Zimmermann"))
@@ -297,18 +297,18 @@ If the result of the METHOD call is just one value, the converted Lisp
297object is returned instead of a list containing this single Lisp object. 297object is returned instead of a list containing this single Lisp object.
298 298
299\(dbus-call-method 299\(dbus-call-method
300 :system "GetPropertyString" "org.freedesktop.Hal" 300 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer"
301 "/org/freedesktop/Hal/devices/computer" "org.freedesktop.Hal.Device" 301 "org.freedesktop.Hal.Device" "GetPropertyString"
302 "system.kernel.machine") 302 "system.kernel.machine")
303 303
304 => "i686" 304 => "i686"
305 305
306usage: (dbus-call-method BUS METHOD SERVICE PATH INTERFACE &rest ARGS) */) 306usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &rest ARGS) */)
307 (nargs, args) 307 (nargs, args)
308 int nargs; 308 int nargs;
309 register Lisp_Object *args; 309 register Lisp_Object *args;
310{ 310{
311 Lisp_Object bus, method, service, path, interface; 311 Lisp_Object bus, service, path, interface, method;
312 Lisp_Object result; 312 Lisp_Object result;
313 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 313 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
314 DBusConnection *connection; 314 DBusConnection *connection;
@@ -316,29 +316,29 @@ usage: (dbus-call-method BUS METHOD SERVICE PATH INTERFACE &rest ARGS) */)
316 DBusMessage *reply; 316 DBusMessage *reply;
317 DBusMessageIter iter; 317 DBusMessageIter iter;
318 DBusError derror; 318 DBusError derror;
319 uint dtype; 319 unsigned int dtype;
320 int i; 320 int i;
321 char *value; 321 char *value;
322 322
323 /* Check parameters. */ 323 /* Check parameters. */
324 bus = args[0]; 324 bus = args[0];
325 method = args[1]; 325 service = args[1];
326 service = args[2]; 326 path = args[2];
327 path = args[3]; 327 interface = args[3];
328 interface = args[4]; 328 method = args[4];
329 329
330 CHECK_SYMBOL (bus); 330 CHECK_SYMBOL (bus);
331 CHECK_STRING (method);
332 CHECK_STRING (service); 331 CHECK_STRING (service);
333 CHECK_STRING (path); 332 CHECK_STRING (path);
334 CHECK_STRING (interface); 333 CHECK_STRING (interface);
335 GCPRO5 (bus, method, service, path, interface); 334 CHECK_STRING (method);
335 GCPRO5 (bus, service, path, interface, method);
336 336
337 XD_DEBUG_MESSAGE ("%s %s %s %s", 337 XD_DEBUG_MESSAGE ("%s %s %s %s",
338 SDATA (method),
339 SDATA (service), 338 SDATA (service),
340 SDATA (path), 339 SDATA (path),
341 SDATA (interface)); 340 SDATA (interface),
341 SDATA (method));
342 342
343 /* Open a connection to the bus. */ 343 /* Open a connection to the bus. */
344 connection = xd_initialize (bus); 344 connection = xd_initialize (bus);
@@ -447,40 +447,41 @@ Other Lisp objects are not supported as arguments of SIGNAL.
447Example: 447Example:
448 448
449\(dbus-send-signal 449\(dbus-send-signal
450 :session "Started" "org.gnu.emacs" "/org/gnu/emacs" "org.gnu.emacs"))) 450 :session "org.gnu.Emacs" "/org/gnu/Emacs"
451 "org.gnu.Emacs.FileManager" "FileModified" "/home/albinus/.emacs")
451 452
452usage: (dbus-send-signal BUS SIGNAL SERVICE PATH INTERFACE &rest ARGS) */) 453usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
453 (nargs, args) 454 (nargs, args)
454 int nargs; 455 int nargs;
455 register Lisp_Object *args; 456 register Lisp_Object *args;
456{ 457{
457 Lisp_Object bus, signal, service, path, interface; 458 Lisp_Object bus, service, path, interface, signal;
458 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 459 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
459 DBusConnection *connection; 460 DBusConnection *connection;
460 DBusMessage *dmessage; 461 DBusMessage *dmessage;
461 uint dtype; 462 unsigned int dtype;
462 int i; 463 int i;
463 char *value; 464 char *value;
464 465
465 /* Check parameters. */ 466 /* Check parameters. */
466 bus = args[0]; 467 bus = args[0];
467 signal = args[1]; 468 service = args[1];
468 service = args[2]; 469 path = args[2];
469 path = args[3]; 470 interface = args[3];
470 interface = args[4]; 471 signal = args[4];
471 472
472 CHECK_SYMBOL (bus); 473 CHECK_SYMBOL (bus);
473 CHECK_STRING (signal);
474 CHECK_STRING (service); 474 CHECK_STRING (service);
475 CHECK_STRING (path); 475 CHECK_STRING (path);
476 CHECK_STRING (interface); 476 CHECK_STRING (interface);
477 GCPRO5 (bus, signal, service, path, interface); 477 CHECK_STRING (signal);
478 GCPRO5 (bus, service, path, interface, signal);
478 479
479 XD_DEBUG_MESSAGE ("%s %s %s %s", 480 XD_DEBUG_MESSAGE ("%s %s %s %s",
480 SDATA (signal),
481 SDATA (service), 481 SDATA (service),
482 SDATA (path), 482 SDATA (path),
483 SDATA (interface)); 483 SDATA (interface),
484 SDATA (signal));
484 485
485 /* Open a connection to the bus. */ 486 /* Open a connection to the bus. */
486 connection = xd_initialize (bus); 487 connection = xd_initialize (bus);
@@ -542,14 +543,17 @@ Lisp_Object
542xd_read_message (bus) 543xd_read_message (bus)
543 Lisp_Object bus; 544 Lisp_Object bus;
544{ 545{
545 Lisp_Object key; 546 Lisp_Object args, key, value;
546 struct gcpro gcpro1; 547 struct gcpro gcpro1;
547 static struct input_event event; 548 static struct input_event event;
548 DBusConnection *connection; 549 DBusConnection *connection;
549 DBusMessage *dmessage; 550 DBusMessage *dmessage;
550 DBusMessageIter iter; 551 DBusMessageIter iter;
551 uint dtype; 552 unsigned int dtype;
552 char service[1024], path[1024], interface[1024], member[1024]; 553 char uname[DBUS_MAXIMUM_NAME_LENGTH];
554 char path[DBUS_MAXIMUM_MATCH_RULE_LENGTH]; /* Unlimited in D-Bus spec. */
555 char interface[DBUS_MAXIMUM_NAME_LENGTH];
556 char member[DBUS_MAXIMUM_NAME_LENGTH];
553 557
554 /* Open a connection to the bus. */ 558 /* Open a connection to the bus. */
555 connection = xd_initialize (bus); 559 connection = xd_initialize (bus);
@@ -562,16 +566,11 @@ xd_read_message (bus)
562 if (dmessage == NULL) 566 if (dmessage == NULL)
563 return; 567 return;
564 568
565 /* There is a message in the queue. Construct the D-Bus event. */
566 XD_DEBUG_MESSAGE ("Event received"); 569 XD_DEBUG_MESSAGE ("Event received");
567 EVENT_INIT (event);
568
569 event.kind = DBUS_EVENT;
570 event.frame_or_window = Qnil;
571 570
572 /* Collect the parameters. */ 571 /* Collect the parameters. */
573 event.arg = Qnil; 572 args = Qnil;
574 GCPRO1 (event.arg); 573 GCPRO1 (args);
575 574
576 if (!dbus_message_iter_init (dmessage, &iter)) 575 if (!dbus_message_iter_init (dmessage, &iter))
577 { 576 {
@@ -583,42 +582,61 @@ xd_read_message (bus)
583 /* Loop over the resulting parameters. Construct a list. */ 582 /* Loop over the resulting parameters. Construct a list. */
584 while ((dtype = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) 583 while ((dtype = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
585 { 584 {
586 event.arg = Fcons (xd_retrieve_arg (dtype, &iter), event.arg); 585 args = Fcons (xd_retrieve_arg (dtype, &iter), args);
587 dbus_message_iter_next (&iter); 586 dbus_message_iter_next (&iter);
588 } 587 }
589 588
590 /* The arguments are stored in reverse order. Reorder them. */ 589 /* The arguments are stored in reverse order. Reorder them. */
591 event.arg = Fnreverse (event.arg); 590 args = Fnreverse (args);
592 591
593 /* Read service, object path interface and member from the 592 /* Read unique name, object path, interface and member from the
594 message. */ 593 message. */
595 strcpy (service, dbus_message_get_sender (dmessage)); 594 strcpy (uname, dbus_message_get_sender (dmessage));
596 strcpy (path, dbus_message_get_path (dmessage)); 595 strcpy (path, dbus_message_get_path (dmessage));
597 strcpy (interface, dbus_message_get_interface (dmessage)); 596 strcpy (interface, dbus_message_get_interface (dmessage));
598 strcpy (member, dbus_message_get_member (dmessage)); 597 strcpy (member, dbus_message_get_member (dmessage));
599 598
600 /* Add them to the event. */ 599 /* Search for a registered function of the message. */
601 event.arg = Fcons ((member == NULL ? Qnil : build_string (member)), 600 key = list3 (bus, build_string (interface), build_string (member));
602 event.arg); 601 value = Fgethash (key, Vdbus_registered_functions_table, Qnil);
603 event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)), 602
604 event.arg); 603 /* Loop over the registered functions. Construct an event. */
605 event.arg = Fcons ((path == NULL ? Qnil : build_string (path)), 604 while (!NILP (value))
606 event.arg); 605 {
607 event.arg = Fcons ((service == NULL ? Qnil : build_string (service)), 606 key = XCAR (value);
608 event.arg); 607 /* key has the structure (SERVICE UNAME PATH HANDLER). */
609 608 if (((uname == NULL)
610 /* Add the bus symbol to the event. */ 609 || (NILP (XCAR (XCDR (key))))
611 event.arg = Fcons (bus, event.arg); 610 || (strcmp (uname, SDATA (XCAR (XCDR (key)))) == 0))
612 611 && ((path == NULL)
613 /* Add the registered function of the message. */ 612 || (NILP (XCAR (XCDR (XCDR (key)))))
614 key = list3 (bus, 613 || (strcmp (path, SDATA (XCAR (XCDR (XCDR (key))))) == 0))
615 (interface == NULL ? Qnil : build_string (interface)), 614 && (!NILP (XCAR (XCDR (XCDR (XCDR (key)))))))
616 (member == NULL ? Qnil : build_string (member))); 615 {
617 event.arg = Fcons (Fgethash (key, Vdbus_registered_functions_table, Qnil), 616 EVENT_INIT (event);
618 event.arg); 617 event.kind = DBUS_EVENT;
619 618 event.frame_or_window = Qnil;
620 /* Store it into the input event queue. */ 619 event.arg = Fcons (XCAR (XCDR (XCDR (XCDR (key)))), args);
621 kbd_buffer_store_event (&event); 620
621 /* Add uname, path, interface and member to the event. */
622 event.arg = Fcons ((member == NULL ? Qnil : build_string (member)),
623 event.arg);
624 event.arg = Fcons ((interface == NULL
625 ? Qnil : build_string (interface)),
626 event.arg);
627 event.arg = Fcons ((path == NULL ? Qnil : build_string (path)),
628 event.arg);
629 event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)),
630 event.arg);
631
632 /* Add the bus symbol to the event. */
633 event.arg = Fcons (bus, event.arg);
634
635 /* Store it into the input event queue. */
636 kbd_buffer_store_event (&event);
637 }
638 value = XCDR (value);
639 }
622 640
623 /* Cleanup. */ 641 /* Cleanup. */
624 dbus_message_unref (dmessage); 642 dbus_message_unref (dmessage);
@@ -666,31 +684,42 @@ SIGNAL and HANDLER must not be nil. Example:
666 (message "Device %s added" device)) 684 (message "Device %s added" device))
667 685
668\(dbus-register-signal 686\(dbus-register-signal
669 :system "DeviceAdded" 687 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/Manager"
670 (dbus-get-name-owner :system "org.freedesktop.Hal") 688 "org.freedesktop.Hal.Manager" "DeviceAdded" 'my-signal-handler)
671 "/org/freedesktop/Hal/Manager" "org.freedesktop.Hal.Manager"
672 'my-signal-handler)
673 689
674 => (:system "org.freedesktop.Hal.Manager" "DeviceAdded") 690 => (:system ":1.3" "/org/freedesktop/Hal/Manager"
691 "org.freedesktop.Hal.Manager" "DeviceAdded")
675 692
676`dbus-register-signal' returns an object, which can be used in 693`dbus-register-signal' returns an object, which can be used in
677`dbus-unregister-signal' for removing the registration. */) 694`dbus-unregister-signal' for removing the registration. */)
678 (bus, signal, service, path, interface, handler) 695 (bus, service, path, interface, signal, handler)
679 Lisp_Object bus, signal, service, path, interface, handler; 696 Lisp_Object bus, service, path, interface, signal, handler;
680{ 697{
681 Lisp_Object key; 698 Lisp_Object unique_name, key, value;
682 DBusConnection *connection; 699 DBusConnection *connection;
683 char rule[1024]; 700 char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
684 DBusError derror; 701 DBusError derror;
685 702
686 /* Check parameters. */ 703 /* Check parameters. */
687 CHECK_SYMBOL (bus); 704 CHECK_SYMBOL (bus);
688 CHECK_STRING (signal);
689 if (!NILP (service)) CHECK_STRING (service); 705 if (!NILP (service)) CHECK_STRING (service);
690 if (!NILP (path)) CHECK_STRING (path); 706 if (!NILP (path)) CHECK_STRING (path);
691 CHECK_STRING (interface); 707 CHECK_STRING (interface);
708 CHECK_STRING (signal);
692 CHECK_SYMBOL (handler); 709 CHECK_SYMBOL (handler);
693 710
711 /* Retrieve unique name of service. If service is a known name, we
712 will register for the corresponding unique name, if any. Signals
713 are sent always with the unique name as sender. Note: the unique
714 name of "org.freedesktop.DBus" is that string itself. */
715 if ((!NILP (service))
716 && (strlen (SDATA (service)) > 0)
717 && (strcmp (SDATA (service), DBUS_SERVICE_DBUS) != 0)
718 && (strncmp (SDATA (service), ":", 1) != 0))
719 unique_name = call2 (intern ("dbus-get-name-owner"), bus, service);
720 else
721 unique_name = service;
722
694 /* Open a connection to the bus. */ 723 /* Open a connection to the bus. */
695 connection = xd_initialize (bus); 724 connection = xd_initialize (bus);
696 725
@@ -700,9 +729,9 @@ SIGNAL and HANDLER must not be nil. Example:
700 SDATA (interface), 729 SDATA (interface),
701 SDATA (signal)); 730 SDATA (signal));
702 731
703 /* Add service and path to the rule if they are non-nil. */ 732 /* Add unique name and path to the rule if they are non-nil. */
704 if (!NILP (service)) 733 if (!NILP (unique_name))
705 sprintf (rule, "%s,sender='%s'%", rule, SDATA (service)); 734 sprintf (rule, "%s,sender='%s'%", rule, SDATA (unique_name));
706 735
707 if (!NILP (path)) 736 if (!NILP (path))
708 sprintf (rule, "%s,path='%s'", rule, SDATA (path)); 737 sprintf (rule, "%s,path='%s'", rule, SDATA (path));
@@ -717,15 +746,21 @@ SIGNAL and HANDLER must not be nil. Example:
717 746
718 /* Create a hash table entry. */ 747 /* Create a hash table entry. */
719 key = list3 (bus, interface, signal); 748 key = list3 (bus, interface, signal);
720 Fputhash (key, handler, Vdbus_registered_functions_table); 749 value = Fgethash (key, Vdbus_registered_functions_table, Qnil);
721 XD_DEBUG_MESSAGE ("\"%s\" registered with handler \"%s\"", 750
722 SDATA (format2 ("%s", key, Qnil)), 751 if (NILP (Fmember (list4 (service, unique_name, path, handler), value)))
723 SDATA (format2 ("%s", handler, Qnil))); 752 Fputhash (key,
753 Fcons (list4 (service, unique_name, path, handler), value),
754 Vdbus_registered_functions_table);
724 755
725 /* Return key. */ 756 /* Return key. */
726 return key; 757 return key;
727} 758}
728 759
760/* The current implementation removes ALL registered functions for a
761 given signal. Shouldn't be a problem in general, but there might
762 be cases it is not desired. Maybe we can refine the
763 implementation. */
729DEFUN ("dbus-unregister-signal", Fdbus_unregister_signal, Sdbus_unregister_signal, 764DEFUN ("dbus-unregister-signal", Fdbus_unregister_signal, Sdbus_unregister_signal,
730 1, 1, 0, 765 1, 1, 0,
731 doc: /* Unregister OBJECT from the D-Bus. 766 doc: /* Unregister OBJECT from the D-Bus.
@@ -734,13 +769,6 @@ OBJECT must be the result of a preceding `dbus-register-signal' call. */)
734 Lisp_Object object; 769 Lisp_Object object;
735{ 770{
736 771
737 /* Check parameters. */
738 CHECK_SYMBOL (object);
739
740 XD_DEBUG_MESSAGE ("\"%s\" unregistered with handler \"%s\"",
741 SDATA (format2 ("%s", object, Qnil)),
742 SDATA (format2 ("%s", Fsymbol_function (object), Qnil)));
743
744 /* Unintern the signal symbol. */ 772 /* Unintern the signal symbol. */
745 Fremhash (object, Vdbus_registered_functions_table); 773 Fremhash (object, Vdbus_registered_functions_table);
746 774
@@ -788,13 +816,19 @@ syms_of_dbusbind ()
788 816
789 DEFVAR_LISP ("dbus-registered-functions-table", &Vdbus_registered_functions_table, 817 DEFVAR_LISP ("dbus-registered-functions-table", &Vdbus_registered_functions_table,
790 doc: /* Hash table of registered functions for D-Bus. 818 doc: /* Hash table of registered functions for D-Bus.
791The key in the hash table is the list (BUS INTERFACE MEMBER). BUS is 819The key in the hash table is the list (BUS MEMBER INTERFACE). BUS is
792either the symbol `:system' or the symbol `:session'. INTERFACE is a 820either the symbol `:system' or the symbol `:session'. INTERFACE is a
793string which denotes a D-Bus interface, and MEMBER, also a string, is 821string which denotes a D-Bus interface, and MEMBER, also a string, is
794either a method or a signal INTERFACE is offering. 822either a method or a signal INTERFACE is offering. All arguments but
795 823BUS must not be nil.
796The value in the hash table a the function to be called when a D-Bus 824
797message, which matches the key criteria, arrives. */); 825The value in the hash table is a list of triple lists
826\((SERVICE UNAME PATH HANDLER) (SERVICE UNAME PATH HANDLER) ...).
827SERVICE is the service name as registered, UNAME is the corresponding
828unique name. PATH is the object path of the sending object. All of
829them be nil, which means a wildcard then. HANDLER is the function to
830be called when a D-Bus message, which matches the key criteria,
831arrives. */);
798 /* We initialize Vdbus_registered_functions_table in dbus.el, 832 /* We initialize Vdbus_registered_functions_table in dbus.el,
799 because we need to define a hash table function first. */ 833 because we need to define a hash table function first. */
800 Vdbus_registered_functions_table = Qnil; 834 Vdbus_registered_functions_table = Qnil;