summaryrefslogtreecommitdiff
path: root/src/dbusbind.c
diff options
context:
space:
mode:
authorMichael Albinus <michael.albinus@gmx.de>2026-01-14 10:41:41 +0100
committerMichael Albinus <michael.albinus@gmx.de>2026-01-14 10:41:41 +0100
commit5a1ced4b243f60918508edace80e6ce5a4f7d09d (patch)
treed20d00b0abb27209ebdfec43b0e376cef345db68 /src/dbusbind.c
parent986aaf06cda0bd1de0c20e3079d824a83e977b69 (diff)
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/dbusbind.c')
-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) */)
return result;
}
+/* Construct a D-Bus event, and store it into the input event queue. */
+static void
+xd_store_event (Lisp_Object handler, Lisp_Object handler_args,
+ Lisp_Object event_args)
+{
+ struct input_event event;
+ EVENT_INIT (event);
+ event.kind = DBUS_EVENT;
+ event.frame_or_window = Qnil;
+ /* Handler and handler args. */
+ event.arg = Fcons (handler, handler_args);
+ /* Event args. */
+ event.arg = CALLN (Fappend, event_args, event.arg);
+ /* Store it into the input event queue. */
+ kbd_buffer_store_event (&event);
+
+ XD_DEBUG_MESSAGE ("Event stored: %s", XD_OBJECT_TO_STRING (event.arg));
+}
+
/* Read one queued incoming message of the D-Bus BUS.
BUS is either a Lisp symbol, :system, :session, :system-private or
:session-private, or a string denoting the bus address. */
static void
xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
{
- Lisp_Object args, key, value;
- struct input_event event;
+ Lisp_Object args, event_args, key, value;
DBusMessage *dmessage;
DBusMessageIter iter;
int dtype;
@@ -1676,6 +1694,27 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
mtype == DBUS_MESSAGE_TYPE_ERROR ? error_name : member,
XD_OBJECT_TO_STRING (args));
+ /* Add type, serial, uname, destination, path, interface and member
+ or error_name to the event_args. */
+ event_args
+ = Fcons (mtype == DBUS_MESSAGE_TYPE_ERROR
+ ? error_name == NULL ? Qnil : build_string (error_name)
+ : member == NULL ? Qnil : build_string (member),
+ Qnil);
+ event_args = Fcons ((interface == NULL ? Qnil : build_string (interface)),
+ event_args);
+ event_args = Fcons ((path == NULL ? Qnil : build_string (path)),
+ event_args);
+ event_args = Fcons ((destination == NULL ? Qnil : build_string (destination)),
+ event_args);
+ event_args = Fcons ((uname == NULL ? Qnil : build_string (uname)),
+ event_args);
+ event_args = Fcons (INT_TO_INTEGER (serial), event_args);
+ event_args = Fcons (make_fixnum (mtype), event_args);
+
+ /* Add the bus symbol to the event. */
+ event_args = Fcons (bus, event_args);
+
if (mtype == DBUS_MESSAGE_TYPE_INVALID)
goto cleanup;
@@ -1693,12 +1732,8 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
/* Remove the entry. */
Fremhash (key, Vdbus_registered_objects_table);
- /* Construct an event. */
- EVENT_INIT (event);
- event.kind = DBUS_EVENT;
- event.frame_or_window = Qnil;
- /* Handler. */
- event.arg = Fcons (value, args);
+ /* Store the event. */
+ xd_store_event (value, args, event_args);
}
else /* DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_SIGNAL. */
@@ -1729,6 +1764,7 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
Fgethash (key, Vdbus_registered_objects_table, Qnil));
}
+ Lisp_Object called_handlers = Qnil;
/* Loop over the registered functions. Construct an event. */
for (; !NILP (value); value = CDR_SAFE (value))
{
@@ -1747,45 +1783,15 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
Lisp_Object handler = CAR_SAFE (CDR_SAFE (key_path_etc));
if (NILP (handler))
continue;
+ if (!NILP (memq_no_quit (handler, called_handlers)))
+ continue;
+ called_handlers = Fcons (handler, called_handlers);
- /* Construct an event and exit the loop. */
- EVENT_INIT (event);
- event.kind = DBUS_EVENT;
- event.frame_or_window = Qnil;
- event.arg = Fcons (handler, args);
- break;
+ /* Store the event. */
+ xd_store_event (handler, args, event_args);
}
-
- if (NILP (value))
- goto monitor;
}
- /* Add type, serial, uname, destination, path, interface and member
- or error_name to the event. */
- event.arg
- = Fcons (mtype == DBUS_MESSAGE_TYPE_ERROR
- ? error_name == NULL ? Qnil : build_string (error_name)
- : member == NULL ? Qnil : build_string (member),
- event.arg);
- event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)),
- event.arg);
- event.arg = Fcons ((path == NULL ? Qnil : build_string (path)),
- event.arg);
- event.arg = Fcons ((destination == NULL ? Qnil : build_string (destination)),
- event.arg);
- event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)),
- event.arg);
- event.arg = Fcons (INT_TO_INTEGER (serial), event.arg);
- event.arg = Fcons (make_fixnum (mtype), event.arg);
-
- /* Add the bus symbol to the event. */
- event.arg = Fcons (bus, event.arg);
-
- /* Store it into the input event queue. */
- kbd_buffer_store_event (&event);
-
- XD_DEBUG_MESSAGE ("Event stored: %s", XD_OBJECT_TO_STRING (event.arg));
-
/* Monitor. */
monitor:
/* Search for a registered function of the message. */
@@ -1796,39 +1802,9 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
if (NILP (value))
goto cleanup;
- /* Construct an event. */
- EVENT_INIT (event);
- event.kind = DBUS_EVENT;
- event.frame_or_window = Qnil;
-
- /* Add type, serial, uname, destination, path, interface, member
- or error_name and handler to the event. */
- event.arg
- = Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (CAR_SAFE (value))))),
- args);
- event.arg
- = Fcons (mtype == DBUS_MESSAGE_TYPE_ERROR
- ? error_name == NULL ? Qnil : build_string (error_name)
- : member == NULL ? Qnil : build_string (member),
- event.arg);
- event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)),
- event.arg);
- event.arg = Fcons ((path == NULL ? Qnil : build_string (path)),
- event.arg);
- event.arg = Fcons ((destination == NULL ? Qnil : build_string (destination)),
- event.arg);
- event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)),
- event.arg);
- event.arg = Fcons (INT_TO_INTEGER (serial), event.arg);
- event.arg = Fcons (make_fixnum (mtype), event.arg);
-
- /* Add the bus symbol to the event. */
- event.arg = Fcons (bus, event.arg);
-
- /* Store it into the input event queue. */
- kbd_buffer_store_event (&event);
-
- XD_DEBUG_MESSAGE ("Monitor event stored: %s", XD_OBJECT_TO_STRING (event.arg));
+ /* Store the event. */
+ xd_store_event (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (CAR_SAFE (value))))),
+ args, event_args);
/* Cleanup. */
cleanup: