diff options
| author | Michael Albinus | 2007-12-08 12:53:37 +0000 |
|---|---|---|
| committer | Michael Albinus | 2007-12-08 12:53:37 +0000 |
| commit | a31d47c7ddfa55bd49b6cfd4b066cd776da459a9 (patch) | |
| tree | e294d0a3414c382fdce27d1f7bc5d95d22a3d444 /src/dbusbind.c | |
| parent | dc56b2ba139f0052c032ff7628ad40c83621740a (diff) | |
| download | emacs-a31d47c7ddfa55bd49b6cfd4b066cd776da459a9.tar.gz emacs-a31d47c7ddfa55bd49b6cfd4b066cd776da459a9.zip | |
* dbusbind.c (xd_read_message): Generate an event for every
registered handler. There might be several handlers registered
for the same signal.
(Fdbus_register_signal): Don't overwrite a registration for the
same signal. Add a new registration if handlers are different.
(Vdbus_registered_functions_table): Rework doc string.
Diffstat (limited to 'src/dbusbind.c')
| -rw-r--r-- | src/dbusbind.c | 127 |
1 files changed, 74 insertions, 53 deletions
diff --git a/src/dbusbind.c b/src/dbusbind.c index 73b538cf599..29835772dc5 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c | |||
| @@ -543,14 +543,14 @@ Lisp_Object | |||
| 543 | xd_read_message (bus) | 543 | xd_read_message (bus) |
| 544 | Lisp_Object bus; | 544 | Lisp_Object bus; |
| 545 | { | 545 | { |
| 546 | Lisp_Object key; | 546 | Lisp_Object args, key, value; |
| 547 | struct gcpro gcpro1; | 547 | struct gcpro gcpro1; |
| 548 | static struct input_event event; | 548 | static struct input_event event; |
| 549 | DBusConnection *connection; | 549 | DBusConnection *connection; |
| 550 | DBusMessage *dmessage; | 550 | DBusMessage *dmessage; |
| 551 | DBusMessageIter iter; | 551 | DBusMessageIter iter; |
| 552 | uint dtype; | 552 | uint dtype; |
| 553 | char service[DBUS_MAXIMUM_NAME_LENGTH]; | 553 | char uname[DBUS_MAXIMUM_NAME_LENGTH]; |
| 554 | char path[DBUS_MAXIMUM_MATCH_RULE_LENGTH]; /* Unlimited in D-Bus spec. */ | 554 | char path[DBUS_MAXIMUM_MATCH_RULE_LENGTH]; /* Unlimited in D-Bus spec. */ |
| 555 | char interface[DBUS_MAXIMUM_NAME_LENGTH]; | 555 | char interface[DBUS_MAXIMUM_NAME_LENGTH]; |
| 556 | char member[DBUS_MAXIMUM_NAME_LENGTH]; | 556 | char member[DBUS_MAXIMUM_NAME_LENGTH]; |
| @@ -566,16 +566,11 @@ xd_read_message (bus) | |||
| 566 | if (dmessage == NULL) | 566 | if (dmessage == NULL) |
| 567 | return; | 567 | return; |
| 568 | 568 | ||
| 569 | /* There is a message in the queue. Construct the D-Bus event. */ | ||
| 570 | XD_DEBUG_MESSAGE ("Event received"); | 569 | XD_DEBUG_MESSAGE ("Event received"); |
| 571 | EVENT_INIT (event); | ||
| 572 | |||
| 573 | event.kind = DBUS_EVENT; | ||
| 574 | event.frame_or_window = Qnil; | ||
| 575 | 570 | ||
| 576 | /* Collect the parameters. */ | 571 | /* Collect the parameters. */ |
| 577 | event.arg = Qnil; | 572 | args = Qnil; |
| 578 | GCPRO1 (event.arg); | 573 | GCPRO1 (args); |
| 579 | 574 | ||
| 580 | if (!dbus_message_iter_init (dmessage, &iter)) | 575 | if (!dbus_message_iter_init (dmessage, &iter)) |
| 581 | { | 576 | { |
| @@ -587,44 +582,59 @@ xd_read_message (bus) | |||
| 587 | /* Loop over the resulting parameters. Construct a list. */ | 582 | /* Loop over the resulting parameters. Construct a list. */ |
| 588 | 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) |
| 589 | { | 584 | { |
| 590 | event.arg = Fcons (xd_retrieve_arg (dtype, &iter), event.arg); | 585 | args = Fcons (xd_retrieve_arg (dtype, &iter), args); |
| 591 | dbus_message_iter_next (&iter); | 586 | dbus_message_iter_next (&iter); |
| 592 | } | 587 | } |
| 593 | 588 | ||
| 594 | /* The arguments are stored in reverse order. Reorder them. */ | 589 | /* The arguments are stored in reverse order. Reorder them. */ |
| 595 | event.arg = Fnreverse (event.arg); | 590 | args = Fnreverse (args); |
| 596 | 591 | ||
| 597 | /* Read service, object path, interface and member from the message. | 592 | /* Read unique name, object path, interface and member from the |
| 598 | The service is always the unique name of the sending object. */ | 593 | message. */ |
| 599 | strcpy (service, dbus_message_get_sender (dmessage)); | 594 | strcpy (uname, dbus_message_get_sender (dmessage)); |
| 600 | strcpy (path, dbus_message_get_path (dmessage)); | 595 | strcpy (path, dbus_message_get_path (dmessage)); |
| 601 | strcpy (interface, dbus_message_get_interface (dmessage)); | 596 | strcpy (interface, dbus_message_get_interface (dmessage)); |
| 602 | strcpy (member, dbus_message_get_member (dmessage)); | 597 | strcpy (member, dbus_message_get_member (dmessage)); |
| 603 | 598 | ||
| 604 | /* Add the registered function of the message. */ | 599 | /* Search for a registered function of the message. */ |
| 605 | key = list5 (bus, | 600 | key = list3 (bus, build_string (interface), build_string (member)); |
| 606 | (service == NULL ? Qnil : build_string (service)), | 601 | value = Fgethash (key, Vdbus_registered_functions_table, Qnil); |
| 607 | (path == NULL ? Qnil : build_string (path)), | 602 | |
| 608 | (interface == NULL ? Qnil : build_string (interface)), | 603 | /* Loop over the registered functions. Construct an event. */ |
| 609 | (member == NULL ? Qnil : build_string (member))); | 604 | while (!NILP (value)) |
| 610 | event.arg = Fcons (Fgethash (key, Vdbus_registered_functions_table, Qnil), | 605 | { |
| 611 | event.arg); | 606 | key = XCAR (value); |
| 612 | 607 | /* key has the structure (SERVICE UNAME PATH HANDLER). */ | |
| 613 | /* Add service, path, interface and member to the event. */ | 608 | if (((uname == NULL) || (NILP (XCAR (XCDR (key)))) || |
| 614 | event.arg = Fcons ((member == NULL ? Qnil : build_string (member)), | 609 | (strcmp (uname, SDATA (XCAR (XCDR (key)))) == 0)) && |
| 615 | event.arg); | 610 | ((path == NULL) || (NILP (XCAR (XCDR (XCDR (key))))) || |
| 616 | event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)), | 611 | (strcmp (path, SDATA (XCAR (XCDR (XCDR (key))))) == 0)) && |
| 617 | event.arg); | 612 | (!NILP (XCAR (XCDR (XCDR (XCDR (key))))))) |
| 618 | event.arg = Fcons ((path == NULL ? Qnil : build_string (path)), | 613 | { |
| 619 | event.arg); | 614 | EVENT_INIT (event); |
| 620 | event.arg = Fcons ((service == NULL ? Qnil : build_string (service)), | 615 | event.kind = DBUS_EVENT; |
| 621 | event.arg); | 616 | event.frame_or_window = Qnil; |
| 622 | 617 | event.arg = Fcons (XCAR (XCDR (XCDR (XCDR (key)))), args); | |
| 623 | /* Add the bus symbol to the event. */ | 618 | |
| 624 | event.arg = Fcons (bus, event.arg); | 619 | /* Add uname, path, interface and member to the event. */ |
| 625 | 620 | event.arg = Fcons ((member == NULL ? Qnil : build_string (member)), | |
| 626 | /* Store it into the input event queue. */ | 621 | event.arg); |
| 627 | kbd_buffer_store_event (&event); | 622 | event.arg = Fcons ((interface == NULL |
| 623 | ? Qnil : build_string (interface)), | ||
| 624 | event.arg); | ||
| 625 | event.arg = Fcons ((path == NULL ? Qnil : build_string (path)), | ||
| 626 | event.arg); | ||
| 627 | event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)), | ||
| 628 | event.arg); | ||
| 629 | |||
| 630 | /* Add the bus symbol to the event. */ | ||
| 631 | event.arg = Fcons (bus, event.arg); | ||
| 632 | |||
| 633 | /* Store it into the input event queue. */ | ||
| 634 | kbd_buffer_store_event (&event); | ||
| 635 | } | ||
| 636 | value = XCDR (value); | ||
| 637 | } | ||
| 628 | 638 | ||
| 629 | /* Cleanup. */ | 639 | /* Cleanup. */ |
| 630 | dbus_message_unref (dmessage); | 640 | dbus_message_unref (dmessage); |
| @@ -683,7 +693,7 @@ SIGNAL and HANDLER must not be nil. Example: | |||
| 683 | (bus, service, path, interface, signal, handler) | 693 | (bus, service, path, interface, signal, handler) |
| 684 | Lisp_Object bus, service, path, interface, signal, handler; | 694 | Lisp_Object bus, service, path, interface, signal, handler; |
| 685 | { | 695 | { |
| 686 | Lisp_Object unique_name, key; | 696 | Lisp_Object unique_name, key, value; |
| 687 | DBusConnection *connection; | 697 | DBusConnection *connection; |
| 688 | char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH]; | 698 | char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH]; |
| 689 | DBusError derror; | 699 | DBusError derror; |
| @@ -701,6 +711,7 @@ SIGNAL and HANDLER must not be nil. Example: | |||
| 701 | are sent always with the unique name as sender. Note: the unique | 711 | are sent always with the unique name as sender. Note: the unique |
| 702 | name of "org.freedesktop.DBus" is that string itself. */ | 712 | name of "org.freedesktop.DBus" is that string itself. */ |
| 703 | if ((!NILP (service)) && | 713 | if ((!NILP (service)) && |
| 714 | (strlen (SDATA (service)) > 0) && | ||
| 704 | (strcmp (SDATA (service), DBUS_SERVICE_DBUS) != 0) && | 715 | (strcmp (SDATA (service), DBUS_SERVICE_DBUS) != 0) && |
| 705 | (strncmp (SDATA (service), ":", 1) != 0)) | 716 | (strncmp (SDATA (service), ":", 1) != 0)) |
| 706 | unique_name = call2 (intern ("dbus-get-name-owner"), bus, service); | 717 | unique_name = call2 (intern ("dbus-get-name-owner"), bus, service); |
| @@ -732,16 +743,22 @@ SIGNAL and HANDLER must not be nil. Example: | |||
| 732 | XD_DEBUG_MESSAGE ("Matching rule \"%s\" created", rule); | 743 | XD_DEBUG_MESSAGE ("Matching rule \"%s\" created", rule); |
| 733 | 744 | ||
| 734 | /* Create a hash table entry. */ | 745 | /* Create a hash table entry. */ |
| 735 | key = list5 (bus, unique_name, path, interface, signal); | 746 | key = list3 (bus, interface, signal); |
| 736 | Fputhash (key, handler, Vdbus_registered_functions_table); | 747 | value = Fgethash (key, Vdbus_registered_functions_table, Qnil); |
| 737 | XD_DEBUG_MESSAGE ("\"%s\" registered with handler \"%s\"", | 748 | |
| 738 | SDATA (format2 ("%s", key, Qnil)), | 749 | if (NILP (Fmember (list4 (service, unique_name, path, handler), value))) |
| 739 | SDATA (format2 ("%s", handler, Qnil))); | 750 | Fputhash (key, |
| 751 | Fcons (list4 (service, unique_name, path, handler), value), | ||
| 752 | Vdbus_registered_functions_table); | ||
| 740 | 753 | ||
| 741 | /* Return key. */ | 754 | /* Return key. */ |
| 742 | return key; | 755 | return key; |
| 743 | } | 756 | } |
| 744 | 757 | ||
| 758 | /* The current implementation removes ALL registered functions for a | ||
| 759 | given signal. Shouldn't be a problem in general, but there might | ||
| 760 | be cases it is not desired. Maybe we can refine the | ||
| 761 | implementation. */ | ||
| 745 | DEFUN ("dbus-unregister-signal", Fdbus_unregister_signal, Sdbus_unregister_signal, | 762 | DEFUN ("dbus-unregister-signal", Fdbus_unregister_signal, Sdbus_unregister_signal, |
| 746 | 1, 1, 0, | 763 | 1, 1, 0, |
| 747 | doc: /* Unregister OBJECT from the D-Bus. | 764 | doc: /* Unregister OBJECT from the D-Bus. |
| @@ -797,15 +814,19 @@ syms_of_dbusbind () | |||
| 797 | 814 | ||
| 798 | DEFVAR_LISP ("dbus-registered-functions-table", &Vdbus_registered_functions_table, | 815 | DEFVAR_LISP ("dbus-registered-functions-table", &Vdbus_registered_functions_table, |
| 799 | doc: /* Hash table of registered functions for D-Bus. | 816 | doc: /* Hash table of registered functions for D-Bus. |
| 800 | The key in the hash table is the list (BUS SERVICE PATH MEMBER INTERFACE). | 817 | The key in the hash table is the list (BUS MEMBER INTERFACE). BUS is |
| 801 | BUS is either the symbol `:system' or the symbol `:session'. SERVICE | 818 | either the symbol `:system' or the symbol `:session'. INTERFACE is a |
| 802 | and PATH are the unique name and the object path of the sending object. | 819 | string which denotes a D-Bus interface, and MEMBER, also a string, is |
| 803 | INTERFACE is a string which denotes a D-Bus interface, and MEMBER, | 820 | either a method or a signal INTERFACE is offering. All arguments but |
| 804 | also a string, is either a method or a signal INTERFACE is offering. | 821 | BUS must not be nil. |
| 805 | All arguments but BUS can be nil, which means a wild card then. | 822 | |
| 806 | 823 | The value in the hash table is a list of triple lists | |
| 807 | The value in the hash table a the function to be called when a D-Bus | 824 | \((SERVICE UNAME PATH HANDLER) (SERVICE UNAME PATH HANDLER) ...). |
| 808 | message, which matches the key criteria, arrives. */); | 825 | SERVICE is the service name as registered, UNAME is the corresponding |
| 826 | unique name. PATH is the object path of the sending object. All of | ||
| 827 | them be nil, which means a wildcard then. HANDLER is the function to | ||
| 828 | be called when a D-Bus message, which matches the key criteria, | ||
| 829 | arrives. */); | ||
| 809 | /* We initialize Vdbus_registered_functions_table in dbus.el, | 830 | /* We initialize Vdbus_registered_functions_table in dbus.el, |
| 810 | because we need to define a hash table function first. */ | 831 | because we need to define a hash table function first. */ |
| 811 | Vdbus_registered_functions_table = Qnil; | 832 | Vdbus_registered_functions_table = Qnil; |