aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Albinus2026-01-14 10:41:41 +0100
committerMichael Albinus2026-01-14 10:41:41 +0100
commit5a1ced4b243f60918508edace80e6ce5a4f7d09d (patch)
treed20d00b0abb27209ebdfec43b0e376cef345db68 /src
parent986aaf06cda0bd1de0c20e3079d824a83e977b69 (diff)
downloademacs-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.c128
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. */
1621static void
1622xd_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. */
1623static void 1642static void
1624xd_read_message_1 (DBusConnection *connection, Lisp_Object bus) 1643xd_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: