diff options
| author | Michael Albinus | 2026-01-14 10:41:41 +0100 |
|---|---|---|
| committer | Michael Albinus | 2026-01-14 10:41:41 +0100 |
| commit | 5a1ced4b243f60918508edace80e6ce5a4f7d09d (patch) | |
| tree | d20d00b0abb27209ebdfec43b0e376cef345db68 /src | |
| parent | 986aaf06cda0bd1de0c20e3079d824a83e977b69 (diff) | |
| download | emacs-5a1ced4b243f60918508edace80e6ce5a4f7d09d.tar.gz emacs-5a1ced4b243f60918508edace80e6ce5a4f7d09d.zip | |
Call all registered D-Bus signal handlers
* doc/misc/dbus.texi (Signals): All registered signal handlers are
called.
(Synchronous Methods, Signals, Monitoring Messages): Add function
result in examples.
* src/dbusbind.c (xd_store_event): New function.
(xd_read_message_1): Use it. Call all registered handlers per
signal. (Bug#80168)
* test/lisp/net/dbus-tests.el (dbus--test-signal-handler): Adapt defun.
(dbus--test-signal-handler1, dbus--test-signal-handler2): New defuns.
(dbus-test05-register-signal-several-handlers): New test.
(dbus-test04-register-method)
(dbus-test04-call-method-authorizable)
(dbus-test05-register-signal)
(dbus-test05-register-signal-with-nils)
(dbus-test06-register-property-emits-signal): Adapt tests.
Diffstat (limited to 'src')
| -rw-r--r-- | src/dbusbind.c | 128 |
1 files changed, 52 insertions, 76 deletions
diff --git a/src/dbusbind.c b/src/dbusbind.c index b79715232fb..a2936011610 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c | |||
| @@ -1617,14 +1617,32 @@ usage: (dbus-message-internal &rest REST) */) | |||
| 1617 | return result; | 1617 | return result; |
| 1618 | } | 1618 | } |
| 1619 | 1619 | ||
| 1620 | /* Construct a D-Bus event, and store it into the input event queue. */ | ||
| 1621 | static void | ||
| 1622 | xd_store_event (Lisp_Object handler, Lisp_Object handler_args, | ||
| 1623 | Lisp_Object event_args) | ||
| 1624 | { | ||
| 1625 | struct input_event event; | ||
| 1626 | EVENT_INIT (event); | ||
| 1627 | event.kind = DBUS_EVENT; | ||
| 1628 | event.frame_or_window = Qnil; | ||
| 1629 | /* Handler and handler args. */ | ||
| 1630 | event.arg = Fcons (handler, handler_args); | ||
| 1631 | /* Event args. */ | ||
| 1632 | event.arg = CALLN (Fappend, event_args, event.arg); | ||
| 1633 | /* Store it into the input event queue. */ | ||
| 1634 | kbd_buffer_store_event (&event); | ||
| 1635 | |||
| 1636 | XD_DEBUG_MESSAGE ("Event stored: %s", XD_OBJECT_TO_STRING (event.arg)); | ||
| 1637 | } | ||
| 1638 | |||
| 1620 | /* Read one queued incoming message of the D-Bus BUS. | 1639 | /* Read one queued incoming message of the D-Bus BUS. |
| 1621 | BUS is either a Lisp symbol, :system, :session, :system-private or | 1640 | BUS is either a Lisp symbol, :system, :session, :system-private or |
| 1622 | :session-private, or a string denoting the bus address. */ | 1641 | :session-private, or a string denoting the bus address. */ |
| 1623 | static void | 1642 | static void |
| 1624 | xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | 1643 | xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) |
| 1625 | { | 1644 | { |
| 1626 | Lisp_Object args, key, value; | 1645 | Lisp_Object args, event_args, key, value; |
| 1627 | struct input_event event; | ||
| 1628 | DBusMessage *dmessage; | 1646 | DBusMessage *dmessage; |
| 1629 | DBusMessageIter iter; | 1647 | DBusMessageIter iter; |
| 1630 | int dtype; | 1648 | int dtype; |
| @@ -1676,6 +1694,27 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1676 | mtype == DBUS_MESSAGE_TYPE_ERROR ? error_name : member, | 1694 | mtype == DBUS_MESSAGE_TYPE_ERROR ? error_name : member, |
| 1677 | XD_OBJECT_TO_STRING (args)); | 1695 | XD_OBJECT_TO_STRING (args)); |
| 1678 | 1696 | ||
| 1697 | /* Add type, serial, uname, destination, path, interface and member | ||
| 1698 | or error_name to the event_args. */ | ||
| 1699 | event_args | ||
| 1700 | = Fcons (mtype == DBUS_MESSAGE_TYPE_ERROR | ||
| 1701 | ? error_name == NULL ? Qnil : build_string (error_name) | ||
| 1702 | : member == NULL ? Qnil : build_string (member), | ||
| 1703 | Qnil); | ||
| 1704 | event_args = Fcons ((interface == NULL ? Qnil : build_string (interface)), | ||
| 1705 | event_args); | ||
| 1706 | event_args = Fcons ((path == NULL ? Qnil : build_string (path)), | ||
| 1707 | event_args); | ||
| 1708 | event_args = Fcons ((destination == NULL ? Qnil : build_string (destination)), | ||
| 1709 | event_args); | ||
| 1710 | event_args = Fcons ((uname == NULL ? Qnil : build_string (uname)), | ||
| 1711 | event_args); | ||
| 1712 | event_args = Fcons (INT_TO_INTEGER (serial), event_args); | ||
| 1713 | event_args = Fcons (make_fixnum (mtype), event_args); | ||
| 1714 | |||
| 1715 | /* Add the bus symbol to the event. */ | ||
| 1716 | event_args = Fcons (bus, event_args); | ||
| 1717 | |||
| 1679 | if (mtype == DBUS_MESSAGE_TYPE_INVALID) | 1718 | if (mtype == DBUS_MESSAGE_TYPE_INVALID) |
| 1680 | goto cleanup; | 1719 | goto cleanup; |
| 1681 | 1720 | ||
| @@ -1693,12 +1732,8 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1693 | /* Remove the entry. */ | 1732 | /* Remove the entry. */ |
| 1694 | Fremhash (key, Vdbus_registered_objects_table); | 1733 | Fremhash (key, Vdbus_registered_objects_table); |
| 1695 | 1734 | ||
| 1696 | /* Construct an event. */ | 1735 | /* Store the event. */ |
| 1697 | EVENT_INIT (event); | 1736 | xd_store_event (value, args, event_args); |
| 1698 | event.kind = DBUS_EVENT; | ||
| 1699 | event.frame_or_window = Qnil; | ||
| 1700 | /* Handler. */ | ||
| 1701 | event.arg = Fcons (value, args); | ||
| 1702 | } | 1737 | } |
| 1703 | 1738 | ||
| 1704 | else /* DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_SIGNAL. */ | 1739 | else /* DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_SIGNAL. */ |
| @@ -1729,6 +1764,7 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1729 | Fgethash (key, Vdbus_registered_objects_table, Qnil)); | 1764 | Fgethash (key, Vdbus_registered_objects_table, Qnil)); |
| 1730 | } | 1765 | } |
| 1731 | 1766 | ||
| 1767 | Lisp_Object called_handlers = Qnil; | ||
| 1732 | /* Loop over the registered functions. Construct an event. */ | 1768 | /* Loop over the registered functions. Construct an event. */ |
| 1733 | for (; !NILP (value); value = CDR_SAFE (value)) | 1769 | for (; !NILP (value); value = CDR_SAFE (value)) |
| 1734 | { | 1770 | { |
| @@ -1747,45 +1783,15 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1747 | Lisp_Object handler = CAR_SAFE (CDR_SAFE (key_path_etc)); | 1783 | Lisp_Object handler = CAR_SAFE (CDR_SAFE (key_path_etc)); |
| 1748 | if (NILP (handler)) | 1784 | if (NILP (handler)) |
| 1749 | continue; | 1785 | continue; |
| 1786 | if (!NILP (memq_no_quit (handler, called_handlers))) | ||
| 1787 | continue; | ||
| 1788 | called_handlers = Fcons (handler, called_handlers); | ||
| 1750 | 1789 | ||
| 1751 | /* Construct an event and exit the loop. */ | 1790 | /* Store the event. */ |
| 1752 | EVENT_INIT (event); | 1791 | xd_store_event (handler, args, event_args); |
| 1753 | event.kind = DBUS_EVENT; | ||
| 1754 | event.frame_or_window = Qnil; | ||
| 1755 | event.arg = Fcons (handler, args); | ||
| 1756 | break; | ||
| 1757 | } | 1792 | } |
| 1758 | |||
| 1759 | if (NILP (value)) | ||
| 1760 | goto monitor; | ||
| 1761 | } | 1793 | } |
| 1762 | 1794 | ||
| 1763 | /* Add type, serial, uname, destination, path, interface and member | ||
| 1764 | or error_name to the event. */ | ||
| 1765 | event.arg | ||
| 1766 | = Fcons (mtype == DBUS_MESSAGE_TYPE_ERROR | ||
| 1767 | ? error_name == NULL ? Qnil : build_string (error_name) | ||
| 1768 | : member == NULL ? Qnil : build_string (member), | ||
| 1769 | event.arg); | ||
| 1770 | event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)), | ||
| 1771 | event.arg); | ||
| 1772 | event.arg = Fcons ((path == NULL ? Qnil : build_string (path)), | ||
| 1773 | event.arg); | ||
| 1774 | event.arg = Fcons ((destination == NULL ? Qnil : build_string (destination)), | ||
| 1775 | event.arg); | ||
| 1776 | event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)), | ||
| 1777 | event.arg); | ||
| 1778 | event.arg = Fcons (INT_TO_INTEGER (serial), event.arg); | ||
| 1779 | event.arg = Fcons (make_fixnum (mtype), event.arg); | ||
| 1780 | |||
| 1781 | /* Add the bus symbol to the event. */ | ||
| 1782 | event.arg = Fcons (bus, event.arg); | ||
| 1783 | |||
| 1784 | /* Store it into the input event queue. */ | ||
| 1785 | kbd_buffer_store_event (&event); | ||
| 1786 | |||
| 1787 | XD_DEBUG_MESSAGE ("Event stored: %s", XD_OBJECT_TO_STRING (event.arg)); | ||
| 1788 | |||
| 1789 | /* Monitor. */ | 1795 | /* Monitor. */ |
| 1790 | monitor: | 1796 | monitor: |
| 1791 | /* Search for a registered function of the message. */ | 1797 | /* Search for a registered function of the message. */ |
| @@ -1796,39 +1802,9 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) | |||
| 1796 | if (NILP (value)) | 1802 | if (NILP (value)) |
| 1797 | goto cleanup; | 1803 | goto cleanup; |
| 1798 | 1804 | ||
| 1799 | /* Construct an event. */ | 1805 | /* Store the event. */ |
| 1800 | EVENT_INIT (event); | 1806 | xd_store_event (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (CAR_SAFE (value))))), |
| 1801 | event.kind = DBUS_EVENT; | 1807 | args, event_args); |
| 1802 | event.frame_or_window = Qnil; | ||
| 1803 | |||
| 1804 | /* Add type, serial, uname, destination, path, interface, member | ||
| 1805 | or error_name and handler to the event. */ | ||
| 1806 | event.arg | ||
| 1807 | = Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (CAR_SAFE (value))))), | ||
| 1808 | args); | ||
| 1809 | event.arg | ||
| 1810 | = Fcons (mtype == DBUS_MESSAGE_TYPE_ERROR | ||
| 1811 | ? error_name == NULL ? Qnil : build_string (error_name) | ||
| 1812 | : member == NULL ? Qnil : build_string (member), | ||
| 1813 | event.arg); | ||
| 1814 | event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)), | ||
| 1815 | event.arg); | ||
| 1816 | event.arg = Fcons ((path == NULL ? Qnil : build_string (path)), | ||
| 1817 | event.arg); | ||
| 1818 | event.arg = Fcons ((destination == NULL ? Qnil : build_string (destination)), | ||
| 1819 | event.arg); | ||
| 1820 | event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)), | ||
| 1821 | event.arg); | ||
| 1822 | event.arg = Fcons (INT_TO_INTEGER (serial), event.arg); | ||
| 1823 | event.arg = Fcons (make_fixnum (mtype), event.arg); | ||
| 1824 | |||
| 1825 | /* Add the bus symbol to the event. */ | ||
| 1826 | event.arg = Fcons (bus, event.arg); | ||
| 1827 | |||
| 1828 | /* Store it into the input event queue. */ | ||
| 1829 | kbd_buffer_store_event (&event); | ||
| 1830 | |||
| 1831 | XD_DEBUG_MESSAGE ("Monitor event stored: %s", XD_OBJECT_TO_STRING (event.arg)); | ||
| 1832 | 1808 | ||
| 1833 | /* Cleanup. */ | 1809 | /* Cleanup. */ |
| 1834 | cleanup: | 1810 | cleanup: |