aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog14
-rw-r--r--src/dbusbind.c142
2 files changed, 103 insertions, 53 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 21e1f9c9df2..51c19d79197 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,17 @@
12007-12-16 Michael Albinus <michael.albinus@gmx.de>
2
3 * dbusbind.c (top): Include <stdio.h>.
4 (Fdbus_call_method, Fdbus_send_signal): Apply type cast in
5 dbus_message_new_method_call and dbus_message_new_signal.
6 (Fdbus_register_signal): Rename unique_name to uname. Check
7 handler for FUNCTIONP instead of CHECK_SYMBOL. Handle case of
8 non-existing unique name. Fix typos in matching rule. Return an
9 object which is useful in Fdbus_unregister_signal.
10 (Fdbus_unregister_signal): Reimplementation, in order to remove
11 only the corresponding entry.
12 (Vdbus_registered_functions_table): Change the order of entries.
13 Apply these changes in xd_read_message and Fdbus_register_signal.
14
12007-12-16 Andreas Schwab <schwab@suse.de> 152007-12-16 Andreas Schwab <schwab@suse.de>
2 16
3 * fileio.c (Finsert_file_contents): Fix overflow check to not 17 * fileio.c (Finsert_file_contents): Fix overflow check to not
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 0ccccc8b22d..d4008f7314c 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -22,6 +22,7 @@ Boston, MA 02110-1301, USA. */
22 22
23#ifdef HAVE_DBUS 23#ifdef HAVE_DBUS
24#include <stdlib.h> 24#include <stdlib.h>
25#include <stdio.h>
25#include <dbus/dbus.h> 26#include <dbus/dbus.h>
26#include "lisp.h" 27#include "lisp.h"
27#include "frame.h" 28#include "frame.h"
@@ -344,10 +345,10 @@ usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &rest ARGS) */)
344 connection = xd_initialize (bus); 345 connection = xd_initialize (bus);
345 346
346 /* Create the message. */ 347 /* Create the message. */
347 dmessage = dbus_message_new_method_call (SDATA (service), 348 dmessage = dbus_message_new_method_call ((char *) SDATA (service),
348 SDATA (path), 349 (char *) SDATA (path),
349 SDATA (interface), 350 (char *) SDATA (interface),
350 SDATA (method)); 351 (char *) SDATA (method));
351 if (dmessage == NULL) 352 if (dmessage == NULL)
352 { 353 {
353 UNGCPRO; 354 UNGCPRO;
@@ -487,9 +488,9 @@ usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
487 connection = xd_initialize (bus); 488 connection = xd_initialize (bus);
488 489
489 /* Create the message. */ 490 /* Create the message. */
490 dmessage = dbus_message_new_signal (SDATA (path), 491 dmessage = dbus_message_new_signal ((char *) SDATA (path),
491 SDATA (interface), 492 (char *) SDATA (interface),
492 SDATA (signal)); 493 (char *) SDATA (signal));
493 if (dmessage == NULL) 494 if (dmessage == NULL)
494 { 495 {
495 UNGCPRO; 496 UNGCPRO;
@@ -604,10 +605,10 @@ xd_read_message (bus)
604 while (!NILP (value)) 605 while (!NILP (value))
605 { 606 {
606 key = XCAR (value); 607 key = XCAR (value);
607 /* key has the structure (SERVICE UNAME PATH HANDLER). */ 608 /* key has the structure (UNAME SERVICE PATH HANDLER). */
608 if (((uname == NULL) 609 if (((uname == NULL)
609 || (NILP (XCAR (XCDR (key)))) 610 || (NILP (XCAR (key)))
610 || (strcmp (uname, SDATA (XCAR (XCDR (key)))) == 0)) 611 || (strcmp (uname, SDATA (XCAR (key))) == 0))
611 && ((path == NULL) 612 && ((path == NULL)
612 || (NILP (XCAR (XCDR (XCDR (key))))) 613 || (NILP (XCAR (XCDR (XCDR (key)))))
613 || (strcmp (path, SDATA (XCAR (XCDR (XCDR (key))))) == 0)) 614 || (strcmp (path, SDATA (XCAR (XCDR (XCDR (key))))) == 0))
@@ -648,10 +649,10 @@ void
648xd_read_queued_messages () 649xd_read_queued_messages ()
649{ 650{
650 651
651 /* Vdbus_registered_functions_table will be made as hash table in 652 /* Vdbus_registered_functions_table will be initialized as hash
652 dbus.el. When it isn't loaded yet, it doesn't make sense to 653 table in dbus.el. When this package isn't loaded yet, it doesn't
653 handle D-Bus messages. Furthermore, we ignore all Lisp errors 654 make sense to handle D-Bus messages. Furthermore, we ignore all
654 during the call. */ 655 Lisp errors during the call. */
655 if (HASH_TABLE_P (Vdbus_registered_functions_table)) 656 if (HASH_TABLE_P (Vdbus_registered_functions_table))
656 { 657 {
657 internal_condition_case_1 (xd_read_message, QCdbus_system_bus, 658 internal_condition_case_1 (xd_read_message, QCdbus_system_bus,
@@ -687,15 +688,15 @@ SIGNAL and HANDLER must not be nil. Example:
687 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/Manager" 688 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/Manager"
688 "org.freedesktop.Hal.Manager" "DeviceAdded" 'my-signal-handler) 689 "org.freedesktop.Hal.Manager" "DeviceAdded" 'my-signal-handler)
689 690
690 => (:system ":1.3" "/org/freedesktop/Hal/Manager" 691 => ((:system "org.freedesktop.Hal.Manager" "DeviceAdded")
691 "org.freedesktop.Hal.Manager" "DeviceAdded") 692 ("org.freedesktop.Hal" "/org/freedesktop/Hal/Manager" my-signal-handler))
692 693
693`dbus-register-signal' returns an object, which can be used in 694`dbus-register-signal' returns an object, which can be used in
694`dbus-unregister-signal' for removing the registration. */) 695`dbus-unregister-signal' for removing the registration. */)
695 (bus, service, path, interface, signal, handler) 696 (bus, service, path, interface, signal, handler)
696 Lisp_Object bus, service, path, interface, signal, handler; 697 Lisp_Object bus, service, path, interface, signal, handler;
697{ 698{
698 Lisp_Object unique_name, key, value; 699 Lisp_Object uname, key, value;
699 DBusConnection *connection; 700 DBusConnection *connection;
700 char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH]; 701 char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
701 DBusError derror; 702 DBusError derror;
@@ -706,7 +707,7 @@ SIGNAL and HANDLER must not be nil. Example:
706 if (!NILP (path)) CHECK_STRING (path); 707 if (!NILP (path)) CHECK_STRING (path);
707 CHECK_STRING (interface); 708 CHECK_STRING (interface);
708 CHECK_STRING (signal); 709 CHECK_STRING (signal);
709 CHECK_SYMBOL (handler); 710 FUNCTIONP (handler);
710 711
711 /* Retrieve unique name of service. If service is a known name, we 712 /* Retrieve unique name of service. If service is a known name, we
712 will register for the corresponding unique name, if any. Signals 713 will register for the corresponding unique name, if any. Signals
@@ -716,51 +717,58 @@ SIGNAL and HANDLER must not be nil. Example:
716 && (strlen (SDATA (service)) > 0) 717 && (strlen (SDATA (service)) > 0)
717 && (strcmp (SDATA (service), DBUS_SERVICE_DBUS) != 0) 718 && (strcmp (SDATA (service), DBUS_SERVICE_DBUS) != 0)
718 && (strncmp (SDATA (service), ":", 1) != 0)) 719 && (strncmp (SDATA (service), ":", 1) != 0))
719 unique_name = call2 (intern ("dbus-get-name-owner"), bus, service); 720 {
721 uname = call2 (intern ("dbus-get-name-owner"), bus, service);
722 /* When there is no unique name, we mark it with an empty
723 string. */
724 if (NILP (uname))
725 uname = build_string ("");
726 }
720 else 727 else
721 unique_name = service; 728 uname = service;
722 729
723 /* Open a connection to the bus. */ 730 /* Create a matching rule if the unique name exists (when no
724 connection = xd_initialize (bus); 731 wildcard). */
732 if (NILP (uname) || (strlen (SDATA (uname)) > 0))
733 {
734 /* Open a connection to the bus. */
735 connection = xd_initialize (bus);
725 736
726 /* Create a rule to receive related signals. */ 737 /* Create a rule to receive related signals. */
727 sprintf (rule, 738 sprintf (rule,
728 "type='signal',interface='%s',member=%s%", 739 "type='signal',interface='%s',member='%s'",
729 SDATA (interface), 740 SDATA (interface),
730 SDATA (signal)); 741 SDATA (signal));
731 742
732 /* Add unique name and path to the rule if they are non-nil. */ 743 /* Add unique name and path to the rule if they are non-nil. */
733 if (!NILP (unique_name)) 744 if (!NILP (uname))
734 sprintf (rule, "%s,sender='%s'%", rule, SDATA (unique_name)); 745 sprintf (rule, "%s,sender='%s'", rule, SDATA (uname));
735 746
736 if (!NILP (path)) 747 if (!NILP (path))
737 sprintf (rule, "%s,path='%s'", rule, SDATA (path)); 748 sprintf (rule, "%s,path='%s'", rule, SDATA (path));
738 749
739 /* Add the rule to the bus. */ 750 /* Add the rule to the bus. */
740 dbus_error_init (&derror); 751 dbus_error_init (&derror);
741 dbus_bus_add_match (connection, rule, &derror); 752 dbus_bus_add_match (connection, rule, &derror);
742 if (dbus_error_is_set (&derror)) 753 if (dbus_error_is_set (&derror))
743 XD_ERROR (derror); 754 XD_ERROR (derror);
744 755
745 XD_DEBUG_MESSAGE ("Matching rule \"%s\" created", rule); 756 XD_DEBUG_MESSAGE ("Matching rule \"%s\" created", rule);
757 }
746 758
747 /* Create a hash table entry. */ 759 /* Create a hash table entry. */
748 key = list3 (bus, interface, signal); 760 key = list3 (bus, interface, signal);
749 value = Fgethash (key, Vdbus_registered_functions_table, Qnil); 761 value = Fgethash (key, Vdbus_registered_functions_table, Qnil);
750 762
751 if (NILP (Fmember (list4 (service, unique_name, path, handler), value))) 763 if (NILP (Fmember (list4 (uname, service, path, handler), value)))
752 Fputhash (key, 764 Fputhash (key,
753 Fcons (list4 (service, unique_name, path, handler), value), 765 Fcons (list4 (uname, service, path, handler), value),
754 Vdbus_registered_functions_table); 766 Vdbus_registered_functions_table);
755 767
756 /* Return key. */ 768 /* Return object. */
757 return key; 769 return list2 (key, list3 (service, path, handler));
758} 770}
759 771
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. */
764DEFUN ("dbus-unregister-signal", Fdbus_unregister_signal, Sdbus_unregister_signal, 772DEFUN ("dbus-unregister-signal", Fdbus_unregister_signal, Sdbus_unregister_signal,
765 1, 1, 0, 773 1, 1, 0,
766 doc: /* Unregister OBJECT from the D-Bus. 774 doc: /* Unregister OBJECT from the D-Bus.
@@ -768,9 +776,37 @@ OBJECT must be the result of a preceding `dbus-register-signal' call. */)
768 (object) 776 (object)
769 Lisp_Object object; 777 Lisp_Object object;
770{ 778{
779 Lisp_Object value;
780 struct gcpro gcpro1;
771 781
772 /* Unintern the signal symbol. */ 782 /* Check parameter. */
773 Fremhash (object, Vdbus_registered_functions_table); 783 CONSP (object) && (!NILP (XCAR (object))) && CONSP (XCDR (object));
784
785 /* Find the corresponding entry in the hash table. */
786 value = Fgethash (XCAR (object), Vdbus_registered_functions_table, Qnil);
787
788 /* Loop over the registered functions. */
789 while (!NILP (value))
790 {
791 GCPRO1 (value);
792
793 /* (car value) has the structure (UNAME SERVICE PATH HANDLER).
794 (cdr object) has the structure ((SERVICE PATH HANDLER) ...). */
795 if (!NILP (Fequal (XCDR (XCAR (value)), XCAR (XCDR (object)))))
796 {
797 /* Compute new hash value. */
798 value = Fdelete (XCAR (value),
799 Fgethash (XCAR (object),
800 Vdbus_registered_functions_table, Qnil));
801 if (NILP (value))
802 Fremhash (XCAR (object), Vdbus_registered_functions_table);
803 else
804 Fputhash (XCAR (object), value, Vdbus_registered_functions_table);
805 RETURN_UNGCPRO (Qt);
806 }
807 UNGCPRO;
808 value = XCDR (value);
809 }
774 810
775 /* Return. */ 811 /* Return. */
776 return Qnil; 812 return Qnil;
@@ -816,18 +852,18 @@ syms_of_dbusbind ()
816 852
817 DEFVAR_LISP ("dbus-registered-functions-table", &Vdbus_registered_functions_table, 853 DEFVAR_LISP ("dbus-registered-functions-table", &Vdbus_registered_functions_table,
818 doc: /* Hash table of registered functions for D-Bus. 854 doc: /* Hash table of registered functions for D-Bus.
819The key in the hash table is the list (BUS MEMBER INTERFACE). BUS is 855The key in the hash table is the list (BUS INTERFACE MEMBER). BUS is
820either the symbol `:system' or the symbol `:session'. INTERFACE is a 856either the symbol `:system' or the symbol `:session'. INTERFACE is a
821string which denotes a D-Bus interface, and MEMBER, also a string, is 857string which denotes a D-Bus interface, and MEMBER, also a string, is
822either a method or a signal INTERFACE is offering. All arguments but 858either a method or a signal INTERFACE is offering. All arguments but
823BUS must not be nil. 859BUS must not be nil.
824 860
825The value in the hash table is a list of triple lists 861The value in the hash table is a list of quadruple lists
826\((SERVICE UNAME PATH HANDLER) (SERVICE UNAME PATH HANDLER) ...). 862\((UNAME SERVICE PATH HANDLER) (UNAME SERVICE PATH HANDLER) ...).
827SERVICE is the service name as registered, UNAME is the corresponding 863SERVICE is the service name as registered, UNAME is the corresponding
828unique name. PATH is the object path of the sending object. All of 864unique 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 865them can be nil, which means a wildcard then. HANDLER is the function
830be called when a D-Bus message, which matches the key criteria, 866to be called when a D-Bus message, which matches the key criteria,
831arrives. */); 867arrives. */);
832 /* We initialize Vdbus_registered_functions_table in dbus.el, 868 /* We initialize Vdbus_registered_functions_table in dbus.el,
833 because we need to define a hash table function first. */ 869 because we need to define a hash table function first. */