1 /* Elisp bindings for D-Bus.
2 Copyright (C) 2007, 2008 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA. */
26 #include <dbus/dbus.h>
29 #include "termhooks.h"
34 Lisp_Object Qdbus_get_unique_name
;
35 Lisp_Object Qdbus_call_method
;
36 Lisp_Object Qdbus_method_return
;
37 Lisp_Object Qdbus_send_signal
;
38 Lisp_Object Qdbus_register_signal
;
39 Lisp_Object Qdbus_register_method
;
40 Lisp_Object Qdbus_unregister_object
;
42 /* D-Bus error symbol. */
43 Lisp_Object Qdbus_error
;
45 /* Lisp symbols of the system and session buses. */
46 Lisp_Object QCdbus_system_bus
, QCdbus_session_bus
;
48 /* Lisp symbols of D-Bus types. */
49 Lisp_Object QCdbus_type_byte
, QCdbus_type_boolean
;
50 Lisp_Object QCdbus_type_int16
, QCdbus_type_uint16
;
51 Lisp_Object QCdbus_type_int32
, QCdbus_type_uint32
;
52 Lisp_Object QCdbus_type_int64
, QCdbus_type_uint64
;
53 Lisp_Object QCdbus_type_double
, QCdbus_type_string
;
54 Lisp_Object QCdbus_type_object_path
, QCdbus_type_signature
;
55 Lisp_Object QCdbus_type_array
, QCdbus_type_variant
;
56 Lisp_Object QCdbus_type_struct
, QCdbus_type_dict_entry
;
58 /* Hash table which keeps function definitions. */
59 Lisp_Object Vdbus_registered_functions_table
;
61 /* Whether to debug D-Bus. */
62 Lisp_Object Vdbus_debug
;
65 /* We use "xd_" and "XD_" as prefix for all internal symbols, because
66 we don't want to poison other namespaces with "dbus_". */
68 /* Raise a Lisp error from a D-Bus ERROR. */
69 #define XD_ERROR(error) \
72 strcpy (s, error.message); \
73 dbus_error_free (&error); \
74 /* Remove the trailing newline. */ \
75 if (strchr (s, '\n') != NULL) \
76 s[strlen (s) - 1] = '\0'; \
77 xsignal1 (Qdbus_error, build_string (s)); \
80 /* Macros for debugging. In order to enable them, build with
81 "make MYCPPFLAGS='-DDBUS_DEBUG -Wall'". */
83 #define XD_DEBUG_MESSAGE(...) \
86 sprintf (s, __VA_ARGS__); \
87 printf ("%s: %s\n", __func__, s); \
88 message ("%s: %s", __func__, s); \
90 #define XD_DEBUG_VALID_LISP_OBJECT_P(object) \
92 if (!valid_lisp_object_p (object)) \
94 XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__); \
95 xsignal1 (Qdbus_error, build_string ("Assertion failure")); \
99 #else /* !DBUS_DEBUG */
100 #define XD_DEBUG_MESSAGE(...) \
102 if (!NILP (Vdbus_debug)) \
105 sprintf (s, __VA_ARGS__); \
106 message ("%s: %s", __func__, s); \
109 #define XD_DEBUG_VALID_LISP_OBJECT_P(object)
112 /* Check whether TYPE is a basic DBusType. */
113 #define XD_BASIC_DBUS_TYPE(type) \
114 ((type == DBUS_TYPE_BYTE) \
115 || (type == DBUS_TYPE_BOOLEAN) \
116 || (type == DBUS_TYPE_INT16) \
117 || (type == DBUS_TYPE_UINT16) \
118 || (type == DBUS_TYPE_INT32) \
119 || (type == DBUS_TYPE_UINT32) \
120 || (type == DBUS_TYPE_INT64) \
121 || (type == DBUS_TYPE_UINT64) \
122 || (type == DBUS_TYPE_DOUBLE) \
123 || (type == DBUS_TYPE_STRING) \
124 || (type == DBUS_TYPE_OBJECT_PATH) \
125 || (type == DBUS_TYPE_SIGNATURE))
127 /* Determine the DBusType of a given Lisp symbol. OBJECT must be one
128 of the predefined D-Bus type symbols. */
129 #define XD_SYMBOL_TO_DBUS_TYPE(object) \
130 ((EQ (object, QCdbus_type_byte)) ? DBUS_TYPE_BYTE \
131 : (EQ (object, QCdbus_type_boolean)) ? DBUS_TYPE_BOOLEAN \
132 : (EQ (object, QCdbus_type_int16)) ? DBUS_TYPE_INT16 \
133 : (EQ (object, QCdbus_type_uint16)) ? DBUS_TYPE_UINT16 \
134 : (EQ (object, QCdbus_type_int32)) ? DBUS_TYPE_INT32 \
135 : (EQ (object, QCdbus_type_uint32)) ? DBUS_TYPE_UINT32 \
136 : (EQ (object, QCdbus_type_int64)) ? DBUS_TYPE_INT64 \
137 : (EQ (object, QCdbus_type_uint64)) ? DBUS_TYPE_UINT64 \
138 : (EQ (object, QCdbus_type_double)) ? DBUS_TYPE_DOUBLE \
139 : (EQ (object, QCdbus_type_string)) ? DBUS_TYPE_STRING \
140 : (EQ (object, QCdbus_type_object_path)) ? DBUS_TYPE_OBJECT_PATH \
141 : (EQ (object, QCdbus_type_signature)) ? DBUS_TYPE_SIGNATURE \
142 : (EQ (object, QCdbus_type_array)) ? DBUS_TYPE_ARRAY \
143 : (EQ (object, QCdbus_type_variant)) ? DBUS_TYPE_VARIANT \
144 : (EQ (object, QCdbus_type_struct)) ? DBUS_TYPE_STRUCT \
145 : (EQ (object, QCdbus_type_dict_entry)) ? DBUS_TYPE_DICT_ENTRY \
148 /* Check whether a Lisp symbol is a predefined D-Bus type symbol. */
149 #define XD_DBUS_TYPE_P(object) \
150 (SYMBOLP (object) && ((XD_SYMBOL_TO_DBUS_TYPE (object) != DBUS_TYPE_INVALID)))
152 /* Determine the DBusType of a given Lisp OBJECT. It is used to
153 convert Lisp objects, being arguments of `dbus-call-method' or
154 `dbus-send-signal', into corresponding C values appended as
155 arguments to a D-Bus message. */
156 #define XD_OBJECT_TO_DBUS_TYPE(object) \
157 ((EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN \
158 : (NATNUMP (object)) ? DBUS_TYPE_UINT32 \
159 : (INTEGERP (object)) ? DBUS_TYPE_INT32 \
160 : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \
161 : (STRINGP (object)) ? DBUS_TYPE_STRING \
162 : (XD_DBUS_TYPE_P (object)) ? XD_SYMBOL_TO_DBUS_TYPE (object) \
163 : (CONSP (object)) ? ((XD_DBUS_TYPE_P (CAR_SAFE (object))) \
164 ? XD_SYMBOL_TO_DBUS_TYPE (CAR_SAFE (object)) \
168 /* Return a list pointer which does not have a Lisp symbol as car. */
169 #define XD_NEXT_VALUE(object) \
170 ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object)
172 /* Compute SIGNATURE of OBJECT. It must have a form that it can be
173 used in dbus_message_iter_open_container. DTYPE is the DBusType
174 the object is related to. It is passed as argument, because it
175 cannot be detected in basic type objects, when they are preceded by
176 a type symbol. PARENT_TYPE is the DBusType of a container this
177 signature is embedded, or DBUS_TYPE_INVALID. It is needed for the
178 check that DBUS_TYPE_DICT_ENTRY occurs only as array element. */
180 xd_signature(signature
, dtype
, parent_type
, object
)
182 unsigned int dtype
, parent_type
;
185 unsigned int subtype
;
187 char x
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
194 case DBUS_TYPE_UINT16
:
195 case DBUS_TYPE_UINT32
:
196 case DBUS_TYPE_UINT64
:
197 CHECK_NATNUM (object
);
198 sprintf (signature
, "%c", dtype
);
201 case DBUS_TYPE_BOOLEAN
:
202 if (!EQ (object
, Qt
) && !EQ (object
, Qnil
))
203 wrong_type_argument (intern ("booleanp"), object
);
204 sprintf (signature
, "%c", dtype
);
207 case DBUS_TYPE_INT16
:
208 case DBUS_TYPE_INT32
:
209 case DBUS_TYPE_INT64
:
210 CHECK_NUMBER (object
);
211 sprintf (signature
, "%c", dtype
);
214 case DBUS_TYPE_DOUBLE
:
215 CHECK_FLOAT (object
);
216 sprintf (signature
, "%c", dtype
);
219 case DBUS_TYPE_STRING
:
220 case DBUS_TYPE_OBJECT_PATH
:
221 case DBUS_TYPE_SIGNATURE
:
222 CHECK_STRING (object
);
223 sprintf (signature
, "%c", dtype
);
226 case DBUS_TYPE_ARRAY
:
227 /* Check that all list elements have the same D-Bus type. For
228 complex element types, we just check the container type, not
229 the whole element's signature. */
232 /* Type symbol is optional. */
233 if (EQ (QCdbus_type_array
, CAR_SAFE (elt
)))
234 elt
= XD_NEXT_VALUE (elt
);
236 /* If the array is empty, DBUS_TYPE_STRING is the default
240 subtype
= DBUS_TYPE_STRING
;
241 strcpy (x
, DBUS_TYPE_STRING_AS_STRING
);
245 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
246 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
249 /* If the element type is DBUS_TYPE_SIGNATURE, and this is the
250 only element, the value of this element is used as he array's
251 element signature. */
252 if ((subtype
== DBUS_TYPE_SIGNATURE
)
253 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt
)))
254 && NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
255 strcpy (x
, SDATA (CAR_SAFE (XD_NEXT_VALUE (elt
))));
259 if (subtype
!= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
)))
260 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (elt
));
261 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
264 sprintf (signature
, "%c%s", dtype
, x
);
267 case DBUS_TYPE_VARIANT
:
268 /* Check that there is exactly one list element. */
271 elt
= XD_NEXT_VALUE (elt
);
272 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
273 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
275 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
276 wrong_type_argument (intern ("D-Bus"),
277 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt
))));
279 sprintf (signature
, "%c", dtype
);
282 case DBUS_TYPE_STRUCT
:
283 /* A struct list might contain any number of elements with
284 different types. No further check needed. */
287 elt
= XD_NEXT_VALUE (elt
);
289 /* Compose the signature from the elements. It is enclosed by
291 sprintf (signature
, "%c", DBUS_STRUCT_BEGIN_CHAR
);
294 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
295 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
296 strcat (signature
, x
);
297 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
299 sprintf (signature
, "%s%c", signature
, DBUS_STRUCT_END_CHAR
);
302 case DBUS_TYPE_DICT_ENTRY
:
303 /* Check that there are exactly two list elements, and the first
304 one is of basic type. The dictionary entry itself must be an
305 element of an array. */
308 /* Check the parent object type. */
309 if (parent_type
!= DBUS_TYPE_ARRAY
)
310 wrong_type_argument (intern ("D-Bus"), object
);
312 /* Compose the signature from the elements. It is enclosed by
314 sprintf (signature
, "%c", DBUS_DICT_ENTRY_BEGIN_CHAR
);
317 elt
= XD_NEXT_VALUE (elt
);
318 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
319 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
320 strcat (signature
, x
);
322 if (!XD_BASIC_DBUS_TYPE (subtype
))
323 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt
)));
325 /* Second element. */
326 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
327 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
328 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
329 strcat (signature
, x
);
331 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
332 wrong_type_argument (intern ("D-Bus"),
333 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt
))));
335 /* Closing signature. */
336 sprintf (signature
, "%s%c", signature
, DBUS_DICT_ENTRY_END_CHAR
);
340 wrong_type_argument (intern ("D-Bus"), object
);
343 XD_DEBUG_MESSAGE ("%s", signature
);
346 /* Append C value, extracted from Lisp OBJECT, to iteration ITER.
347 DTYPE must be a valid DBusType. It is used to convert Lisp
348 objects, being arguments of `dbus-call-method' or
349 `dbus-send-signal', into corresponding C values appended as
350 arguments to a D-Bus message. */
352 xd_append_arg (dtype
, object
, iter
)
355 DBusMessageIter
*iter
;
357 char signature
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
358 DBusMessageIter subiter
;
360 if (XD_BASIC_DBUS_TYPE (dtype
))
365 unsigned char val
= XUINT (object
) & 0xFF;
366 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
367 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
368 xsignal2 (Qdbus_error
,
369 build_string ("Unable to append argument"), object
);
373 case DBUS_TYPE_BOOLEAN
:
375 dbus_bool_t val
= (NILP (object
)) ? FALSE
: TRUE
;
376 XD_DEBUG_MESSAGE ("%c %s", dtype
, (val
== FALSE
) ? "false" : "true");
377 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
378 xsignal2 (Qdbus_error
,
379 build_string ("Unable to append argument"), object
);
383 case DBUS_TYPE_INT16
:
385 dbus_int16_t val
= XINT (object
);
386 XD_DEBUG_MESSAGE ("%c %d", dtype
, (int) val
);
387 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
388 xsignal2 (Qdbus_error
,
389 build_string ("Unable to append argument"), object
);
393 case DBUS_TYPE_UINT16
:
395 dbus_uint16_t val
= XUINT (object
);
396 XD_DEBUG_MESSAGE ("%c %u", dtype
, (unsigned int) val
);
397 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
398 xsignal2 (Qdbus_error
,
399 build_string ("Unable to append argument"), object
);
403 case DBUS_TYPE_INT32
:
405 dbus_int32_t val
= XINT (object
);
406 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
407 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
408 xsignal2 (Qdbus_error
,
409 build_string ("Unable to append argument"), object
);
413 case DBUS_TYPE_UINT32
:
415 dbus_uint32_t val
= XUINT (object
);
416 XD_DEBUG_MESSAGE ("%c %u", dtype
, val
);
417 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
418 xsignal2 (Qdbus_error
,
419 build_string ("Unable to append argument"), object
);
423 case DBUS_TYPE_INT64
:
425 dbus_int64_t val
= XINT (object
);
426 XD_DEBUG_MESSAGE ("%c %d", dtype
, (int) val
);
427 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
428 xsignal2 (Qdbus_error
,
429 build_string ("Unable to append argument"), object
);
433 case DBUS_TYPE_UINT64
:
435 dbus_uint64_t val
= XUINT (object
);
436 XD_DEBUG_MESSAGE ("%c %u", dtype
, (unsigned int) val
);
437 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
438 xsignal2 (Qdbus_error
,
439 build_string ("Unable to append argument"), object
);
443 case DBUS_TYPE_DOUBLE
:
444 XD_DEBUG_MESSAGE ("%c %f", dtype
, XFLOAT_DATA (object
));
445 if (!dbus_message_iter_append_basic (iter
, dtype
,
446 &XFLOAT_DATA (object
)))
447 xsignal2 (Qdbus_error
,
448 build_string ("Unable to append argument"), object
);
451 case DBUS_TYPE_STRING
:
452 case DBUS_TYPE_OBJECT_PATH
:
453 case DBUS_TYPE_SIGNATURE
:
455 char *val
= SDATA (object
);
456 XD_DEBUG_MESSAGE ("%c %s", dtype
, val
);
457 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
458 xsignal2 (Qdbus_error
,
459 build_string ("Unable to append argument"), object
);
464 else /* Compound types. */
467 /* All compound types except array have a type symbol. For
468 array, it is optional. Skip it. */
469 if (!XD_BASIC_DBUS_TYPE (XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
))))
470 object
= XD_NEXT_VALUE (object
);
472 /* Open new subiteration. */
475 case DBUS_TYPE_ARRAY
:
476 /* An array has only elements of the same type. So it is
477 sufficient to check the first element's signature
481 /* If the array is empty, DBUS_TYPE_STRING is the default
483 strcpy (signature
, DBUS_TYPE_STRING_AS_STRING
);
486 /* If the element type is DBUS_TYPE_SIGNATURE, and this is
487 the only element, the value of this element is used as
488 the array's element signature. */
489 if ((XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
))
490 == DBUS_TYPE_SIGNATURE
)
491 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object
)))
492 && NILP (CDR_SAFE (XD_NEXT_VALUE (object
))))
494 strcpy (signature
, SDATA (CAR_SAFE (XD_NEXT_VALUE (object
))));
495 object
= CDR_SAFE (XD_NEXT_VALUE (object
));
499 xd_signature (signature
,
500 XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
)),
501 dtype
, CAR_SAFE (XD_NEXT_VALUE (object
)));
503 XD_DEBUG_MESSAGE ("%c %s %s", dtype
, signature
,
504 SDATA (format2 ("%s", object
, Qnil
)));
505 if (!dbus_message_iter_open_container (iter
, dtype
,
506 signature
, &subiter
))
507 xsignal3 (Qdbus_error
,
508 build_string ("Cannot open container"),
509 make_number (dtype
), build_string (signature
));
512 case DBUS_TYPE_VARIANT
:
513 /* A variant has just one element. */
514 xd_signature (signature
, XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
)),
515 dtype
, CAR_SAFE (XD_NEXT_VALUE (object
)));
517 XD_DEBUG_MESSAGE ("%c %s %s", dtype
, signature
,
518 SDATA (format2 ("%s", object
, Qnil
)));
519 if (!dbus_message_iter_open_container (iter
, dtype
,
520 signature
, &subiter
))
521 xsignal3 (Qdbus_error
,
522 build_string ("Cannot open container"),
523 make_number (dtype
), build_string (signature
));
526 case DBUS_TYPE_STRUCT
:
527 case DBUS_TYPE_DICT_ENTRY
:
528 /* These containers do not require a signature. */
529 XD_DEBUG_MESSAGE ("%c %s", dtype
,
530 SDATA (format2 ("%s", object
, Qnil
)));
531 if (!dbus_message_iter_open_container (iter
, dtype
, NULL
, &subiter
))
532 xsignal2 (Qdbus_error
,
533 build_string ("Cannot open container"),
534 make_number (dtype
));
538 /* Loop over list elements. */
539 while (!NILP (object
))
541 dtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
));
542 object
= XD_NEXT_VALUE (object
);
544 xd_append_arg (dtype
, CAR_SAFE (object
), &subiter
);
546 object
= CDR_SAFE (object
);
549 /* Close the subiteration. */
550 if (!dbus_message_iter_close_container (iter
, &subiter
))
551 xsignal2 (Qdbus_error
,
552 build_string ("Cannot close container"),
553 make_number (dtype
));
557 /* Retrieve C value from a DBusMessageIter structure ITER, and return
558 a converted Lisp object. The type DTYPE of the argument of the
559 D-Bus message must be a valid DBusType. Compound D-Bus types
560 result always in a Lisp list. */
562 xd_retrieve_arg (dtype
, iter
)
564 DBusMessageIter
*iter
;
572 dbus_message_iter_get_basic (iter
, &val
);
574 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
575 return make_number (val
);
578 case DBUS_TYPE_BOOLEAN
:
581 dbus_message_iter_get_basic (iter
, &val
);
582 XD_DEBUG_MESSAGE ("%c %s", dtype
, (val
== FALSE
) ? "false" : "true");
583 return (val
== FALSE
) ? Qnil
: Qt
;
586 case DBUS_TYPE_INT16
:
587 case DBUS_TYPE_UINT16
:
590 dbus_message_iter_get_basic (iter
, &val
);
591 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
592 return make_number (val
);
595 case DBUS_TYPE_INT32
:
596 case DBUS_TYPE_UINT32
:
599 dbus_message_iter_get_basic (iter
, &val
);
600 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
601 return make_fixnum_or_float (val
);
604 case DBUS_TYPE_INT64
:
605 case DBUS_TYPE_UINT64
:
608 dbus_message_iter_get_basic (iter
, &val
);
609 XD_DEBUG_MESSAGE ("%c %d", dtype
, (int) val
);
610 return make_fixnum_or_float (val
);
613 case DBUS_TYPE_DOUBLE
:
616 dbus_message_iter_get_basic (iter
, &val
);
617 XD_DEBUG_MESSAGE ("%c %f", dtype
, val
);
618 return make_float (val
);
621 case DBUS_TYPE_STRING
:
622 case DBUS_TYPE_OBJECT_PATH
:
623 case DBUS_TYPE_SIGNATURE
:
626 dbus_message_iter_get_basic (iter
, &val
);
627 XD_DEBUG_MESSAGE ("%c %s", dtype
, val
);
628 return build_string (val
);
631 case DBUS_TYPE_ARRAY
:
632 case DBUS_TYPE_VARIANT
:
633 case DBUS_TYPE_STRUCT
:
634 case DBUS_TYPE_DICT_ENTRY
:
640 DBusMessageIter subiter
;
642 dbus_message_iter_recurse (iter
, &subiter
);
643 while ((subtype
= dbus_message_iter_get_arg_type (&subiter
))
644 != DBUS_TYPE_INVALID
)
646 result
= Fcons (xd_retrieve_arg (subtype
, &subiter
), result
);
647 dbus_message_iter_next (&subiter
);
649 XD_DEBUG_MESSAGE ("%c %s", dtype
, SDATA (format2 ("%s", result
, Qnil
)));
650 RETURN_UNGCPRO (Fnreverse (result
));
654 XD_DEBUG_MESSAGE ("DBusType '%c' not supported", dtype
);
659 /* Initialize D-Bus connection. BUS is a Lisp symbol, either :system
660 or :session. It tells which D-Bus to be initialized. */
665 DBusConnection
*connection
;
668 /* Parameter check. */
670 if (!((EQ (bus
, QCdbus_system_bus
)) || (EQ (bus
, QCdbus_session_bus
))))
671 xsignal2 (Qdbus_error
, build_string ("Wrong bus name"), bus
);
673 /* Open a connection to the bus. */
674 dbus_error_init (&derror
);
676 if (EQ (bus
, QCdbus_system_bus
))
677 connection
= dbus_bus_get (DBUS_BUS_SYSTEM
, &derror
);
679 connection
= dbus_bus_get (DBUS_BUS_SESSION
, &derror
);
681 if (dbus_error_is_set (&derror
))
684 if (connection
== NULL
)
685 xsignal2 (Qdbus_error
, build_string ("No connection"), bus
);
687 /* Return the result. */
691 DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name
, Sdbus_get_unique_name
,
693 doc
: /* Return the unique name of Emacs registered at D-Bus BUS. */)
697 DBusConnection
*connection
;
698 char name
[DBUS_MAXIMUM_NAME_LENGTH
];
700 /* Check parameters. */
703 /* Open a connection to the bus. */
704 connection
= xd_initialize (bus
);
706 /* Request the name. */
707 strcpy (name
, dbus_bus_get_unique_name (connection
));
709 xsignal1 (Qdbus_error
, build_string ("No unique name available"));
712 return build_string (name
);
715 DEFUN ("dbus-call-method", Fdbus_call_method
, Sdbus_call_method
, 5, MANY
, 0,
716 doc
: /* Call METHOD on the D-Bus BUS.
718 BUS is either the symbol `:system' or the symbol `:session'.
720 SERVICE is the D-Bus service name to be used. PATH is the D-Bus
721 object path SERVICE is registered at. INTERFACE is an interface
722 offered by SERVICE. It must provide METHOD.
724 All other arguments ARGS are passed to METHOD as arguments. They are
725 converted into D-Bus types via the following rules:
727 t and nil => DBUS_TYPE_BOOLEAN
728 number => DBUS_TYPE_UINT32
729 integer => DBUS_TYPE_INT32
730 float => DBUS_TYPE_DOUBLE
731 string => DBUS_TYPE_STRING
732 list => DBUS_TYPE_ARRAY
734 All arguments can be preceded by a type symbol. For details about
735 type symbols, see Info node `(dbus)Type Conversion'.
737 `dbus-call-method' returns the resulting values of METHOD as a list of
738 Lisp objects. The type conversion happens the other direction as for
739 input arguments. It follows the mapping rules:
741 DBUS_TYPE_BOOLEAN => t or nil
742 DBUS_TYPE_BYTE => number
743 DBUS_TYPE_UINT16 => number
744 DBUS_TYPE_INT16 => integer
745 DBUS_TYPE_UINT32 => number or float
746 DBUS_TYPE_INT32 => integer or float
747 DBUS_TYPE_UINT64 => number or float
748 DBUS_TYPE_INT64 => integer or float
749 DBUS_TYPE_DOUBLE => float
750 DBUS_TYPE_STRING => string
751 DBUS_TYPE_OBJECT_PATH => string
752 DBUS_TYPE_SIGNATURE => string
753 DBUS_TYPE_ARRAY => list
754 DBUS_TYPE_VARIANT => list
755 DBUS_TYPE_STRUCT => list
756 DBUS_TYPE_DICT_ENTRY => list
761 :session "org.gnome.seahorse" "/org/gnome/seahorse/keys/openpgp"
762 "org.gnome.seahorse.Keys" "GetKeyField"
763 "openpgp:657984B8C7A966DD" "simple-name")
765 => (t ("Philip R. Zimmermann"))
767 If the result of the METHOD call is just one value, the converted Lisp
768 object is returned instead of a list containing this single Lisp object.
771 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer"
772 "org.freedesktop.Hal.Device" "GetPropertyString"
773 "system.kernel.machine")
777 usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &rest ARGS) */)
780 register Lisp_Object
*args
;
782 Lisp_Object bus
, service
, path
, interface
, method
;
784 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
785 DBusConnection
*connection
;
786 DBusMessage
*dmessage
;
788 DBusMessageIter iter
;
792 char signature
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
794 /* Check parameters. */
802 CHECK_STRING (service
);
804 CHECK_STRING (interface
);
805 CHECK_STRING (method
);
806 GCPRO5 (bus
, service
, path
, interface
, method
);
808 XD_DEBUG_MESSAGE ("%s %s %s %s",
814 /* Open a connection to the bus. */
815 connection
= xd_initialize (bus
);
817 /* Create the message. */
818 dmessage
= dbus_message_new_method_call (SDATA (service
),
822 if (dmessage
== NULL
)
825 xsignal1 (Qdbus_error
, build_string ("Unable to create a new message"));
830 /* Initialize parameter list of message. */
831 dbus_message_iter_init_append (dmessage
, &iter
);
833 /* Append parameters to the message. */
834 for (i
= 5; i
< nargs
; ++i
)
837 XD_DEBUG_VALID_LISP_OBJECT_P (args
[i
]);
838 XD_DEBUG_MESSAGE ("Parameter%d %s",
839 i
-4, SDATA (format2 ("%s", args
[i
], Qnil
)));
841 dtype
= XD_OBJECT_TO_DBUS_TYPE (args
[i
]);
842 if (XD_DBUS_TYPE_P (args
[i
]))
845 /* Check for valid signature. We use DBUS_TYPE_INVALID as
846 indication that there is no parent type. */
847 xd_signature (signature
, dtype
, DBUS_TYPE_INVALID
, args
[i
]);
849 xd_append_arg (dtype
, args
[i
], &iter
);
852 /* Send the message. */
853 dbus_error_init (&derror
);
854 reply
= dbus_connection_send_with_reply_and_block (connection
,
859 if (dbus_error_is_set (&derror
))
863 xsignal1 (Qdbus_error
, build_string ("No reply"));
865 XD_DEBUG_MESSAGE ("Message sent");
867 /* Collect the results. */
871 if (dbus_message_iter_init (reply
, &iter
))
873 /* Loop over the parameters of the D-Bus reply message. Construct a
874 Lisp list, which is returned by `dbus-call-method'. */
875 while ((dtype
= dbus_message_iter_get_arg_type (&iter
)) != DBUS_TYPE_INVALID
)
877 result
= Fcons (xd_retrieve_arg (dtype
, &iter
), result
);
878 dbus_message_iter_next (&iter
);
883 /* No arguments: just return nil. */
887 dbus_message_unref (dmessage
);
888 dbus_message_unref (reply
);
890 /* Return the result. If there is only one single Lisp object,
891 return it as-it-is, otherwise return the reversed list. */
892 if (XUINT (Flength (result
)) == 1)
893 RETURN_UNGCPRO (CAR_SAFE (result
));
895 RETURN_UNGCPRO (Fnreverse (result
));
898 DEFUN ("dbus-method-return", Fdbus_method_return
, Sdbus_method_return
,
900 doc
: /* Return to method SERIAL on the D-Bus BUS.
901 This is an internal function, it shall not be used outside dbus.el.
903 usage: (dbus-method-return BUS SERIAL SERVICE &rest ARGS) */)
906 register Lisp_Object
*args
;
908 Lisp_Object bus
, serial
, service
;
909 struct gcpro gcpro1
, gcpro2
, gcpro3
;
910 DBusConnection
*connection
;
911 DBusMessage
*dmessage
;
912 DBusMessageIter iter
;
915 char signature
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
917 /* Check parameters. */
923 CHECK_NUMBER (serial
);
924 CHECK_STRING (service
);
925 GCPRO3 (bus
, serial
, service
);
927 XD_DEBUG_MESSAGE ("%d %s ", XUINT (serial
), SDATA (service
));
929 /* Open a connection to the bus. */
930 connection
= xd_initialize (bus
);
932 /* Create the message. */
933 dmessage
= dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN
);
934 if ((dmessage
== NULL
)
935 || (!dbus_message_set_reply_serial (dmessage
, XUINT (serial
)))
936 || (!dbus_message_set_destination (dmessage
, SDATA (service
))))
939 xsignal1 (Qdbus_error
,
940 build_string ("Unable to create a return message"));
945 /* Initialize parameter list of message. */
946 dbus_message_iter_init_append (dmessage
, &iter
);
948 /* Append parameters to the message. */
949 for (i
= 3; i
< nargs
; ++i
)
952 XD_DEBUG_VALID_LISP_OBJECT_P (args
[i
]);
953 XD_DEBUG_MESSAGE ("Parameter%d %s",
954 i
-2, SDATA (format2 ("%s", args
[i
], Qnil
)));
956 dtype
= XD_OBJECT_TO_DBUS_TYPE (args
[i
]);
957 if (XD_DBUS_TYPE_P (args
[i
]))
960 /* Check for valid signature. We use DBUS_TYPE_INVALID as
961 indication that there is no parent type. */
962 xd_signature (signature
, dtype
, DBUS_TYPE_INVALID
, args
[i
]);
964 xd_append_arg (dtype
, args
[i
], &iter
);
967 /* Send the message. The message is just added to the outgoing
969 if (!dbus_connection_send (connection
, dmessage
, NULL
))
970 xsignal1 (Qdbus_error
, build_string ("Cannot send message"));
972 /* Flush connection to ensure the message is handled. */
973 dbus_connection_flush (connection
);
975 XD_DEBUG_MESSAGE ("Message sent");
978 dbus_message_unref (dmessage
);
984 DEFUN ("dbus-send-signal", Fdbus_send_signal
, Sdbus_send_signal
, 5, MANY
, 0,
985 doc
: /* Send signal SIGNAL on the D-Bus BUS.
987 BUS is either the symbol `:system' or the symbol `:session'.
989 SERVICE is the D-Bus service name SIGNAL is sent from. PATH is the
990 D-Bus object path SERVICE is registered at. INTERFACE is an interface
991 offered by SERVICE. It must provide signal SIGNAL.
993 All other arguments ARGS are passed to SIGNAL as arguments. They are
994 converted into D-Bus types via the following rules:
996 t and nil => DBUS_TYPE_BOOLEAN
997 number => DBUS_TYPE_UINT32
998 integer => DBUS_TYPE_INT32
999 float => DBUS_TYPE_DOUBLE
1000 string => DBUS_TYPE_STRING
1001 list => DBUS_TYPE_ARRAY
1003 All arguments can be preceded by a type symbol. For details about
1004 type symbols, see Info node `(dbus)Type Conversion'.
1009 :session "org.gnu.Emacs" "/org/gnu/Emacs"
1010 "org.gnu.Emacs.FileManager" "FileModified" "/home/albinus/.emacs")
1012 usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
1015 register Lisp_Object
*args
;
1017 Lisp_Object bus
, service
, path
, interface
, signal
;
1018 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
1019 DBusConnection
*connection
;
1020 DBusMessage
*dmessage
;
1021 DBusMessageIter iter
;
1024 char signature
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
1026 /* Check parameters. */
1030 interface
= args
[3];
1034 CHECK_STRING (service
);
1035 CHECK_STRING (path
);
1036 CHECK_STRING (interface
);
1037 CHECK_STRING (signal
);
1038 GCPRO5 (bus
, service
, path
, interface
, signal
);
1040 XD_DEBUG_MESSAGE ("%s %s %s %s",
1046 /* Open a connection to the bus. */
1047 connection
= xd_initialize (bus
);
1049 /* Create the message. */
1050 dmessage
= dbus_message_new_signal (SDATA (path
),
1053 if (dmessage
== NULL
)
1056 xsignal1 (Qdbus_error
, build_string ("Unable to create a new message"));
1061 /* Initialize parameter list of message. */
1062 dbus_message_iter_init_append (dmessage
, &iter
);
1064 /* Append parameters to the message. */
1065 for (i
= 5; i
< nargs
; ++i
)
1067 XD_DEBUG_VALID_LISP_OBJECT_P (args
[i
]);
1068 XD_DEBUG_MESSAGE ("Parameter%d %s",
1069 i
-4, SDATA (format2 ("%s", args
[i
], Qnil
)));
1071 dtype
= XD_OBJECT_TO_DBUS_TYPE (args
[i
]);
1072 if (XD_DBUS_TYPE_P (args
[i
]))
1075 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1076 indication that there is no parent type. */
1077 xd_signature (signature
, dtype
, DBUS_TYPE_INVALID
, args
[i
]);
1079 xd_append_arg (dtype
, args
[i
], &iter
);
1082 /* Send the message. The message is just added to the outgoing
1084 if (!dbus_connection_send (connection
, dmessage
, NULL
))
1085 xsignal1 (Qdbus_error
, build_string ("Cannot send message"));
1087 /* Flush connection to ensure the message is handled. */
1088 dbus_connection_flush (connection
);
1090 XD_DEBUG_MESSAGE ("Signal sent");
1093 dbus_message_unref (dmessage
);
1099 /* Read queued incoming message of the D-Bus BUS. BUS is a Lisp
1100 symbol, either :system or :session. */
1102 xd_read_message (bus
)
1105 Lisp_Object args
, key
, value
;
1106 struct gcpro gcpro1
;
1107 struct input_event event
;
1108 DBusConnection
*connection
;
1109 DBusMessage
*dmessage
;
1110 DBusMessageIter iter
;
1113 char uname
[DBUS_MAXIMUM_NAME_LENGTH
];
1114 char path
[DBUS_MAXIMUM_MATCH_RULE_LENGTH
]; /* Unlimited in D-Bus spec. */
1115 char interface
[DBUS_MAXIMUM_NAME_LENGTH
];
1116 char member
[DBUS_MAXIMUM_NAME_LENGTH
];
1118 /* Open a connection to the bus. */
1119 connection
= xd_initialize (bus
);
1121 /* Non blocking read of the next available message. */
1122 dbus_connection_read_write (connection
, 0);
1123 dmessage
= dbus_connection_pop_message (connection
);
1125 /* Return if there is no queued message. */
1126 if (dmessage
== NULL
)
1129 /* Collect the parameters. */
1133 /* Loop over the resulting parameters. Construct a list. */
1134 if (dbus_message_iter_init (dmessage
, &iter
))
1136 while ((dtype
= dbus_message_iter_get_arg_type (&iter
))
1137 != DBUS_TYPE_INVALID
)
1139 args
= Fcons (xd_retrieve_arg (dtype
, &iter
), args
);
1140 dbus_message_iter_next (&iter
);
1142 /* The arguments are stored in reverse order. Reorder them. */
1143 args
= Fnreverse (args
);
1146 /* Read message type, unique name, object path, interface and member
1147 from the message. */
1148 mtype
= dbus_message_get_type (dmessage
);
1149 strcpy (uname
, dbus_message_get_sender (dmessage
));
1150 strcpy (path
, dbus_message_get_path (dmessage
));
1151 strcpy (interface
, dbus_message_get_interface (dmessage
));
1152 strcpy (member
, dbus_message_get_member (dmessage
));
1154 XD_DEBUG_MESSAGE ("Event received: %d %s %s %s %s %s",
1155 mtype
, uname
, path
, interface
, member
,
1156 SDATA (format2 ("%s", args
, Qnil
)));
1158 /* Search for a registered function of the message. */
1159 key
= list3 (bus
, build_string (interface
), build_string (member
));
1160 value
= Fgethash (key
, Vdbus_registered_functions_table
, Qnil
);
1162 /* Loop over the registered functions. Construct an event. */
1163 while (!NILP (value
))
1165 key
= CAR_SAFE (value
);
1166 /* key has the structure (UNAME SERVICE PATH HANDLER). */
1167 if (((uname
== NULL
)
1168 || (NILP (CAR_SAFE (key
)))
1169 || (strcmp (uname
, SDATA (CAR_SAFE (key
))) == 0))
1171 || (NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))
1172 || (strcmp (path
, SDATA (CAR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))
1174 && (!NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))))
1177 event
.kind
= DBUS_EVENT
;
1178 event
.frame_or_window
= Qnil
;
1179 event
.arg
= Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key
)))),
1182 /* Add uname, path, interface and member to the event. */
1183 event
.arg
= Fcons ((member
== NULL
? Qnil
: build_string (member
)),
1185 event
.arg
= Fcons ((interface
== NULL
1186 ? Qnil
: build_string (interface
)),
1188 event
.arg
= Fcons ((path
== NULL
? Qnil
: build_string (path
)),
1190 event
.arg
= Fcons ((uname
== NULL
? Qnil
: build_string (uname
)),
1193 /* Add the message serial if needed, or nil. */
1194 event
.arg
= Fcons ((mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
1195 ? make_number (dbus_message_get_serial (dmessage
))
1199 /* Add the bus symbol to the event. */
1200 event
.arg
= Fcons (bus
, event
.arg
);
1202 /* Store it into the input event queue. */
1203 kbd_buffer_store_event (&event
);
1205 value
= CDR_SAFE (value
);
1209 dbus_message_unref (dmessage
);
1210 RETURN_UNGCPRO (Qnil
);
1213 /* Read queued incoming messages from the system and session buses. */
1215 xd_read_queued_messages ()
1218 /* Vdbus_registered_functions_table will be initialized as hash
1219 table in dbus.el. When this package isn't loaded yet, it doesn't
1220 make sense to handle D-Bus messages. Furthermore, we ignore all
1221 Lisp errors during the call. */
1222 if (HASH_TABLE_P (Vdbus_registered_functions_table
))
1224 internal_condition_case_1 (xd_read_message
, QCdbus_system_bus
,
1226 internal_condition_case_1 (xd_read_message
, QCdbus_session_bus
,
1231 DEFUN ("dbus-register-signal", Fdbus_register_signal
, Sdbus_register_signal
,
1233 doc
: /* Register for signal SIGNAL on the D-Bus BUS.
1235 BUS is either the symbol `:system' or the symbol `:session'.
1237 SERVICE is the D-Bus service name used by the sending D-Bus object.
1238 It can be either a known name or the unique name of the D-Bus object
1239 sending the signal. When SERVICE is nil, related signals from all
1240 D-Bus objects shall be accepted.
1242 PATH is the D-Bus object path SERVICE is registered. It can also be
1243 nil if the path name of incoming signals shall not be checked.
1245 INTERFACE is an interface offered by SERVICE. It must provide SIGNAL.
1246 HANDLER is a Lisp function to be called when the signal is received.
1247 It must accept as arguments the values SIGNAL is sending. INTERFACE,
1248 SIGNAL and HANDLER must not be nil. Example:
1250 \(defun my-signal-handler (device)
1251 (message "Device %s added" device))
1253 \(dbus-register-signal
1254 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/Manager"
1255 "org.freedesktop.Hal.Manager" "DeviceAdded" 'my-signal-handler)
1257 => ((:system "org.freedesktop.Hal.Manager" "DeviceAdded")
1258 ("org.freedesktop.Hal" "/org/freedesktop/Hal/Manager" my-signal-handler))
1260 `dbus-register-signal' returns an object, which can be used in
1261 `dbus-unregister-object' for removing the registration. */)
1262 (bus
, service
, path
, interface
, signal
, handler
)
1263 Lisp_Object bus
, service
, path
, interface
, signal
, handler
;
1265 Lisp_Object uname
, key
, key1
, value
;
1266 DBusConnection
*connection
;
1267 char rule
[DBUS_MAXIMUM_MATCH_RULE_LENGTH
];
1270 /* Check parameters. */
1272 if (!NILP (service
)) CHECK_STRING (service
);
1273 if (!NILP (path
)) CHECK_STRING (path
);
1274 CHECK_STRING (interface
);
1275 CHECK_STRING (signal
);
1276 if (!FUNCTIONP (handler
))
1277 wrong_type_argument (intern ("functionp"), handler
);
1279 /* Retrieve unique name of service. If service is a known name, we
1280 will register for the corresponding unique name, if any. Signals
1281 are sent always with the unique name as sender. Note: the unique
1282 name of "org.freedesktop.DBus" is that string itself. */
1283 if ((STRINGP (service
))
1284 && (SBYTES (service
) > 0)
1285 && (strcmp (SDATA (service
), DBUS_SERVICE_DBUS
) != 0)
1286 && (strncmp (SDATA (service
), ":", 1) != 0))
1288 uname
= call2 (intern ("dbus-get-name-owner"), bus
, service
);
1289 /* When there is no unique name, we mark it with an empty
1292 uname
= build_string ("");
1297 /* Create a matching rule if the unique name exists (when no
1299 if (NILP (uname
) || (SBYTES (uname
) > 0))
1301 /* Open a connection to the bus. */
1302 connection
= xd_initialize (bus
);
1304 /* Create a rule to receive related signals. */
1306 "type='signal',interface='%s',member='%s'",
1310 /* Add unique name and path to the rule if they are non-nil. */
1312 sprintf (rule
, "%s,sender='%s'", rule
, SDATA (uname
));
1315 sprintf (rule
, "%s,path='%s'", rule
, SDATA (path
));
1317 /* Add the rule to the bus. */
1318 dbus_error_init (&derror
);
1319 dbus_bus_add_match (connection
, rule
, &derror
);
1320 if (dbus_error_is_set (&derror
))
1323 XD_DEBUG_MESSAGE ("Matching rule \"%s\" created", rule
);
1326 /* Create a hash table entry. */
1327 key
= list3 (bus
, interface
, signal
);
1328 key1
= list4 (uname
, service
, path
, handler
);
1329 value
= Fgethash (key
, Vdbus_registered_functions_table
, Qnil
);
1331 if (NILP (Fmember (key1
, value
)))
1332 Fputhash (key
, Fcons (key1
, value
), Vdbus_registered_functions_table
);
1334 /* Return object. */
1335 return list2 (key
, list3 (service
, path
, handler
));
1338 DEFUN ("dbus-register-method", Fdbus_register_method
, Sdbus_register_method
,
1340 doc
: /* Register for method METHOD on the D-Bus BUS.
1342 BUS is either the symbol `:system' or the symbol `:session'.
1344 SERVICE is the D-Bus service name of the D-Bus object METHOD is
1345 registered for. It must be a known name.
1347 PATH is the D-Bus object path SERVICE is registered. INTERFACE is the
1348 interface offered by SERVICE. It must provide METHOD. HANDLER is a
1349 Lisp function to be called when a method call is received. It must
1350 accept the input arguments of METHOD. The return value of HANDLER is
1351 used for composing the returning D-Bus message. */)
1352 (bus
, service
, path
, interface
, method
, handler
)
1353 Lisp_Object bus
, service
, path
, interface
, method
, handler
;
1355 Lisp_Object key
, key1
, value
;
1356 DBusConnection
*connection
;
1360 /* Check parameters. */
1362 CHECK_STRING (service
);
1363 CHECK_STRING (path
);
1364 CHECK_STRING (interface
);
1365 CHECK_STRING (method
);
1366 if (!FUNCTIONP (handler
))
1367 wrong_type_argument (intern ("functionp"), handler
);
1368 /* TODO: We must check for a valid service name, otherwise there is
1369 a segmentation fault. */
1371 /* Open a connection to the bus. */
1372 connection
= xd_initialize (bus
);
1374 /* Request the known name from the bus. We can ignore the result,
1375 it is set to -1 if there is an error - kind of redundancy. */
1376 dbus_error_init (&derror
);
1377 result
= dbus_bus_request_name (connection
, SDATA (service
), 0, &derror
);
1378 if (dbus_error_is_set (&derror
))
1381 /* Create a hash table entry. */
1382 key
= list3 (bus
, interface
, method
);
1383 key1
= list4 (Qnil
, service
, path
, handler
);
1384 value
= Fgethash (key
, Vdbus_registered_functions_table
, Qnil
);
1386 /* We use nil for the unique name, because the method might be
1387 called from everybody. */
1388 if (NILP (Fmember (key1
, value
)))
1389 Fputhash (key
, Fcons (key1
, value
), Vdbus_registered_functions_table
);
1391 /* Return object. */
1392 return list2 (key
, list3 (service
, path
, handler
));
1395 DEFUN ("dbus-unregister-object", Fdbus_unregister_object
,
1396 Sdbus_unregister_object
,
1398 doc
: /* Unregister OBJECT from the D-Bus.
1399 OBJECT must be the result of a preceding `dbus-register-signal' or
1400 `dbus-register-method' call. It returns t if OBJECT has been
1401 unregistered, nil otherwise. */)
1406 struct gcpro gcpro1
;
1408 /* Check parameter. */
1409 if (!(CONSP (object
) && (!NILP (CAR_SAFE (object
)))
1410 && CONSP (CDR_SAFE (object
))))
1411 wrong_type_argument (intern ("D-Bus"), object
);
1413 /* Find the corresponding entry in the hash table. */
1414 value
= Fgethash (CAR_SAFE (object
), Vdbus_registered_functions_table
, Qnil
);
1416 /* Loop over the registered functions. */
1417 while (!NILP (value
))
1421 /* (car value) has the structure (UNAME SERVICE PATH HANDLER).
1422 (cdr object) has the structure ((SERVICE PATH HANDLER) ...). */
1423 if (!NILP (Fequal (CDR_SAFE (CAR_SAFE (value
)),
1424 CAR_SAFE (CDR_SAFE (object
)))))
1426 /* Compute new hash value. */
1427 value
= Fdelete (CAR_SAFE (value
),
1428 Fgethash (CAR_SAFE (object
),
1429 Vdbus_registered_functions_table
, Qnil
));
1431 Fremhash (CAR_SAFE (object
), Vdbus_registered_functions_table
);
1433 Fputhash (CAR_SAFE (object
), value
,
1434 Vdbus_registered_functions_table
);
1435 RETURN_UNGCPRO (Qt
);
1438 value
= CDR_SAFE (value
);
1450 Qdbus_get_unique_name
= intern ("dbus-get-unique-name");
1451 staticpro (&Qdbus_get_unique_name
);
1452 defsubr (&Sdbus_get_unique_name
);
1454 Qdbus_call_method
= intern ("dbus-call-method");
1455 staticpro (&Qdbus_call_method
);
1456 defsubr (&Sdbus_call_method
);
1458 Qdbus_method_return
= intern ("dbus-method-return");
1459 staticpro (&Qdbus_method_return
);
1460 defsubr (&Sdbus_method_return
);
1462 Qdbus_send_signal
= intern ("dbus-send-signal");
1463 staticpro (&Qdbus_send_signal
);
1464 defsubr (&Sdbus_send_signal
);
1466 Qdbus_register_signal
= intern ("dbus-register-signal");
1467 staticpro (&Qdbus_register_signal
);
1468 defsubr (&Sdbus_register_signal
);
1470 Qdbus_register_method
= intern ("dbus-register-method");
1471 staticpro (&Qdbus_register_method
);
1472 defsubr (&Sdbus_register_method
);
1474 Qdbus_unregister_object
= intern ("dbus-unregister-object");
1475 staticpro (&Qdbus_unregister_object
);
1476 defsubr (&Sdbus_unregister_object
);
1478 Qdbus_error
= intern ("dbus-error");
1479 staticpro (&Qdbus_error
);
1480 Fput (Qdbus_error
, Qerror_conditions
,
1481 list2 (Qdbus_error
, Qerror
));
1482 Fput (Qdbus_error
, Qerror_message
,
1483 build_string ("D-Bus error"));
1485 QCdbus_system_bus
= intern (":system");
1486 staticpro (&QCdbus_system_bus
);
1488 QCdbus_session_bus
= intern (":session");
1489 staticpro (&QCdbus_session_bus
);
1491 QCdbus_type_byte
= intern (":byte");
1492 staticpro (&QCdbus_type_byte
);
1494 QCdbus_type_boolean
= intern (":boolean");
1495 staticpro (&QCdbus_type_boolean
);
1497 QCdbus_type_int16
= intern (":int16");
1498 staticpro (&QCdbus_type_int16
);
1500 QCdbus_type_uint16
= intern (":uint16");
1501 staticpro (&QCdbus_type_uint16
);
1503 QCdbus_type_int32
= intern (":int32");
1504 staticpro (&QCdbus_type_int32
);
1506 QCdbus_type_uint32
= intern (":uint32");
1507 staticpro (&QCdbus_type_uint32
);
1509 QCdbus_type_int64
= intern (":int64");
1510 staticpro (&QCdbus_type_int64
);
1512 QCdbus_type_uint64
= intern (":uint64");
1513 staticpro (&QCdbus_type_uint64
);
1515 QCdbus_type_double
= intern (":double");
1516 staticpro (&QCdbus_type_double
);
1518 QCdbus_type_string
= intern (":string");
1519 staticpro (&QCdbus_type_string
);
1521 QCdbus_type_object_path
= intern (":object-path");
1522 staticpro (&QCdbus_type_object_path
);
1524 QCdbus_type_signature
= intern (":signature");
1525 staticpro (&QCdbus_type_signature
);
1527 QCdbus_type_array
= intern (":array");
1528 staticpro (&QCdbus_type_array
);
1530 QCdbus_type_variant
= intern (":variant");
1531 staticpro (&QCdbus_type_variant
);
1533 QCdbus_type_struct
= intern (":struct");
1534 staticpro (&QCdbus_type_struct
);
1536 QCdbus_type_dict_entry
= intern (":dict-entry");
1537 staticpro (&QCdbus_type_dict_entry
);
1539 DEFVAR_LISP ("dbus-registered-functions-table",
1540 &Vdbus_registered_functions_table
,
1541 doc
: /* Hash table of registered functions for D-Bus.
1542 The key in the hash table is the list (BUS INTERFACE MEMBER). BUS is
1543 either the symbol `:system' or the symbol `:session'. INTERFACE is a
1544 string which denotes a D-Bus interface, and MEMBER, also a string, is
1545 either a method or a signal INTERFACE is offering. All arguments but
1546 BUS must not be nil.
1548 The value in the hash table is a list of quadruple lists
1549 \((UNAME SERVICE PATH HANDLER) (UNAME SERVICE PATH HANDLER) ...).
1550 SERVICE is the service name as registered, UNAME is the corresponding
1551 unique name. PATH is the object path of the sending object. All of
1552 them can be nil, which means a wildcard then. HANDLER is the function
1553 to be called when a D-Bus message, which matches the key criteria,
1555 /* We initialize Vdbus_registered_functions_table in dbus.el,
1556 because we need to define a hash table function first. */
1557 Vdbus_registered_functions_table
= Qnil
;
1559 DEFVAR_LISP ("dbus-debug", &Vdbus_debug
,
1560 doc
: /* If non-nil, debug messages of D-Bus bindings are raised. */);
1567 Fprovide (intern ("dbusbind"), Qnil
);
1571 #endif /* HAVE_DBUS */
1573 /* arch-tag: 0e828477-b571-4fe4-b559-5c9211bc14b8
1574 (do not change this comment) */