diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 14 | ||||
| -rw-r--r-- | src/dbusbind.c | 142 |
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 @@ | |||
| 1 | 2007-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 | |||
| 1 | 2007-12-16 Andreas Schwab <schwab@suse.de> | 15 | 2007-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 | |||
| 648 | xd_read_queued_messages () | 649 | xd_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. */ | ||
| 764 | DEFUN ("dbus-unregister-signal", Fdbus_unregister_signal, Sdbus_unregister_signal, | 772 | DEFUN ("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. |
| 819 | The key in the hash table is the list (BUS MEMBER INTERFACE). BUS is | 855 | The key in the hash table is the list (BUS INTERFACE MEMBER). BUS is |
| 820 | either the symbol `:system' or the symbol `:session'. INTERFACE is a | 856 | either the symbol `:system' or the symbol `:session'. INTERFACE is a |
| 821 | string which denotes a D-Bus interface, and MEMBER, also a string, is | 857 | string which denotes a D-Bus interface, and MEMBER, also a string, is |
| 822 | either a method or a signal INTERFACE is offering. All arguments but | 858 | either a method or a signal INTERFACE is offering. All arguments but |
| 823 | BUS must not be nil. | 859 | BUS must not be nil. |
| 824 | 860 | ||
| 825 | The value in the hash table is a list of triple lists | 861 | The 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) ...). |
| 827 | SERVICE is the service name as registered, UNAME is the corresponding | 863 | SERVICE is the service name as registered, UNAME is the corresponding |
| 828 | unique name. PATH is the object path of the sending object. All of | 864 | unique name. PATH is the object path of the sending object. All of |
| 829 | them be nil, which means a wildcard then. HANDLER is the function to | 865 | them can be nil, which means a wildcard then. HANDLER is the function |
| 830 | be called when a D-Bus message, which matches the key criteria, | 866 | to be called when a D-Bus message, which matches the key criteria, |
| 831 | arrives. */); | 867 | arrives. */); |
| 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. */ |