1 /* Elisp bindings for D-Bus.
2 Copyright (C) 2007-2014 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 of the License, or
9 (at your option) any later version.
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. If not, see <http://www.gnu.org/licenses/>. */
23 #include <dbus/dbus.h>
27 #include "termhooks.h"
31 #ifndef DBUS_NUM_MESSAGE_TYPES
32 #define DBUS_NUM_MESSAGE_TYPES 5
36 /* Some platforms define the symbol "interface", but we want to use it
37 * as a variable name below. */
45 static Lisp_Object Qdbus_init_bus
;
46 static Lisp_Object Qdbus_get_unique_name
;
47 static Lisp_Object Qdbus_message_internal
;
49 /* D-Bus error symbol. */
50 static Lisp_Object Qdbus_error
;
52 /* Lisp symbols of the system and session buses. */
53 static Lisp_Object QCdbus_system_bus
, QCdbus_session_bus
;
55 /* Lisp symbol for method call timeout. */
56 static Lisp_Object QCdbus_timeout
;
58 /* Lisp symbols of D-Bus types. */
59 static Lisp_Object QCdbus_type_byte
, QCdbus_type_boolean
;
60 static Lisp_Object QCdbus_type_int16
, QCdbus_type_uint16
;
61 static Lisp_Object QCdbus_type_int32
, QCdbus_type_uint32
;
62 static Lisp_Object QCdbus_type_int64
, QCdbus_type_uint64
;
63 static Lisp_Object QCdbus_type_double
, QCdbus_type_string
;
64 static Lisp_Object QCdbus_type_object_path
, QCdbus_type_signature
;
65 #ifdef DBUS_TYPE_UNIX_FD
66 static Lisp_Object QCdbus_type_unix_fd
;
68 static Lisp_Object QCdbus_type_array
, QCdbus_type_variant
;
69 static Lisp_Object QCdbus_type_struct
, QCdbus_type_dict_entry
;
71 /* Lisp symbols of objects in `dbus-registered-objects-table'. */
72 static Lisp_Object QCdbus_registered_serial
, QCdbus_registered_method
;
73 static Lisp_Object QCdbus_registered_signal
;
75 /* Alist of D-Bus buses we are polling for messages.
76 The key is the symbol or string of the bus, and the value is the
77 connection address. */
78 static Lisp_Object xd_registered_buses
;
80 /* Whether we are reading a D-Bus event. */
81 static bool xd_in_read_queued_messages
= 0;
84 /* We use "xd_" and "XD_" as prefix for all internal symbols, because
85 we don't want to poison other namespaces with "dbus_". */
87 /* Raise a signal. If we are reading events, we cannot signal; we
88 throw to xd_read_queued_messages then. */
89 #define XD_SIGNAL1(arg) \
91 if (xd_in_read_queued_messages) \
92 Fthrow (Qdbus_error, Qnil); \
94 xsignal1 (Qdbus_error, arg); \
97 #define XD_SIGNAL2(arg1, arg2) \
99 if (xd_in_read_queued_messages) \
100 Fthrow (Qdbus_error, Qnil); \
102 xsignal2 (Qdbus_error, arg1, arg2); \
105 #define XD_SIGNAL3(arg1, arg2, arg3) \
107 if (xd_in_read_queued_messages) \
108 Fthrow (Qdbus_error, Qnil); \
110 xsignal3 (Qdbus_error, arg1, arg2, arg3); \
113 /* Raise a Lisp error from a D-Bus ERROR. */
114 #define XD_ERROR(error) \
116 /* Remove the trailing newline. */ \
117 char const *mess = error.message; \
118 char const *nl = strchr (mess, '\n'); \
119 Lisp_Object err = make_string (mess, nl ? nl - mess : strlen (mess)); \
120 dbus_error_free (&error); \
124 /* Macros for debugging. In order to enable them, build with
125 "env MYCPPFLAGS='-DDBUS_DEBUG -Wall' make". */
127 #define XD_DEBUG_MESSAGE(...) \
130 snprintf (s, sizeof s, __VA_ARGS__); \
131 if (!noninteractive) \
132 printf ("%s: %s\n", __func__, s); \
133 message ("%s: %s", __func__, s); \
135 #define XD_DEBUG_VALID_LISP_OBJECT_P(object) \
137 if (!valid_lisp_object_p (object)) \
139 XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__); \
140 XD_SIGNAL1 (build_string ("Assertion failure")); \
144 #else /* !DBUS_DEBUG */
145 # if __STDC_VERSION__ < 199901
146 # define XD_DEBUG_MESSAGE (void) /* Pre-C99 compilers cannot debug. */
148 # define XD_DEBUG_MESSAGE(...) \
150 if (!NILP (Vdbus_debug)) \
153 snprintf (s, sizeof s, __VA_ARGS__); \
154 message ("%s: %s", __func__, s); \
158 # define XD_DEBUG_VALID_LISP_OBJECT_P(object)
161 /* Check whether TYPE is a basic DBusType. */
162 #ifdef HAVE_DBUS_TYPE_IS_VALID
163 #define XD_BASIC_DBUS_TYPE(type) \
164 (dbus_type_is_valid (type) && dbus_type_is_basic (type))
166 #ifdef DBUS_TYPE_UNIX_FD
167 #define XD_BASIC_DBUS_TYPE(type) \
168 ((type == DBUS_TYPE_BYTE) \
169 || (type == DBUS_TYPE_BOOLEAN) \
170 || (type == DBUS_TYPE_INT16) \
171 || (type == DBUS_TYPE_UINT16) \
172 || (type == DBUS_TYPE_INT32) \
173 || (type == DBUS_TYPE_UINT32) \
174 || (type == DBUS_TYPE_INT64) \
175 || (type == DBUS_TYPE_UINT64) \
176 || (type == DBUS_TYPE_DOUBLE) \
177 || (type == DBUS_TYPE_STRING) \
178 || (type == DBUS_TYPE_OBJECT_PATH) \
179 || (type == DBUS_TYPE_SIGNATURE) \
180 || (type == DBUS_TYPE_UNIX_FD))
182 #define XD_BASIC_DBUS_TYPE(type) \
183 ((type == DBUS_TYPE_BYTE) \
184 || (type == DBUS_TYPE_BOOLEAN) \
185 || (type == DBUS_TYPE_INT16) \
186 || (type == DBUS_TYPE_UINT16) \
187 || (type == DBUS_TYPE_INT32) \
188 || (type == DBUS_TYPE_UINT32) \
189 || (type == DBUS_TYPE_INT64) \
190 || (type == DBUS_TYPE_UINT64) \
191 || (type == DBUS_TYPE_DOUBLE) \
192 || (type == DBUS_TYPE_STRING) \
193 || (type == DBUS_TYPE_OBJECT_PATH) \
194 || (type == DBUS_TYPE_SIGNATURE))
198 /* This was a macro. On Solaris 2.11 it was said to compile for
199 hours, when optimization is enabled. So we have transferred it into
201 /* Determine the DBusType of a given Lisp symbol. OBJECT must be one
202 of the predefined D-Bus type symbols. */
204 xd_symbol_to_dbus_type (Lisp_Object object
)
207 ((EQ (object
, QCdbus_type_byte
)) ? DBUS_TYPE_BYTE
208 : (EQ (object
, QCdbus_type_boolean
)) ? DBUS_TYPE_BOOLEAN
209 : (EQ (object
, QCdbus_type_int16
)) ? DBUS_TYPE_INT16
210 : (EQ (object
, QCdbus_type_uint16
)) ? DBUS_TYPE_UINT16
211 : (EQ (object
, QCdbus_type_int32
)) ? DBUS_TYPE_INT32
212 : (EQ (object
, QCdbus_type_uint32
)) ? DBUS_TYPE_UINT32
213 : (EQ (object
, QCdbus_type_int64
)) ? DBUS_TYPE_INT64
214 : (EQ (object
, QCdbus_type_uint64
)) ? DBUS_TYPE_UINT64
215 : (EQ (object
, QCdbus_type_double
)) ? DBUS_TYPE_DOUBLE
216 : (EQ (object
, QCdbus_type_string
)) ? DBUS_TYPE_STRING
217 : (EQ (object
, QCdbus_type_object_path
)) ? DBUS_TYPE_OBJECT_PATH
218 : (EQ (object
, QCdbus_type_signature
)) ? DBUS_TYPE_SIGNATURE
219 #ifdef DBUS_TYPE_UNIX_FD
220 : (EQ (object
, QCdbus_type_unix_fd
)) ? DBUS_TYPE_UNIX_FD
222 : (EQ (object
, QCdbus_type_array
)) ? DBUS_TYPE_ARRAY
223 : (EQ (object
, QCdbus_type_variant
)) ? DBUS_TYPE_VARIANT
224 : (EQ (object
, QCdbus_type_struct
)) ? DBUS_TYPE_STRUCT
225 : (EQ (object
, QCdbus_type_dict_entry
)) ? DBUS_TYPE_DICT_ENTRY
226 : DBUS_TYPE_INVALID
);
229 /* Check whether a Lisp symbol is a predefined D-Bus type symbol. */
230 #define XD_DBUS_TYPE_P(object) \
231 (SYMBOLP (object) && ((xd_symbol_to_dbus_type (object) != DBUS_TYPE_INVALID)))
233 /* Determine the DBusType of a given Lisp OBJECT. It is used to
234 convert Lisp objects, being arguments of `dbus-call-method' or
235 `dbus-send-signal', into corresponding C values appended as
236 arguments to a D-Bus message. */
237 #define XD_OBJECT_TO_DBUS_TYPE(object) \
238 ((EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN \
239 : (NATNUMP (object)) ? DBUS_TYPE_UINT32 \
240 : (INTEGERP (object)) ? DBUS_TYPE_INT32 \
241 : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \
242 : (STRINGP (object)) ? DBUS_TYPE_STRING \
243 : (XD_DBUS_TYPE_P (object)) ? xd_symbol_to_dbus_type (object) \
245 ? ((XD_DBUS_TYPE_P (CAR_SAFE (object))) \
246 ? ((XD_BASIC_DBUS_TYPE (xd_symbol_to_dbus_type (CAR_SAFE (object)))) \
248 : xd_symbol_to_dbus_type (CAR_SAFE (object))) \
252 /* Return a list pointer which does not have a Lisp symbol as car. */
253 #define XD_NEXT_VALUE(object) \
254 ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object)
256 /* Transform the message type to its string representation for debug
258 #define XD_MESSAGE_TYPE_TO_STRING(mtype) \
259 ((mtype == DBUS_MESSAGE_TYPE_INVALID) \
260 ? "DBUS_MESSAGE_TYPE_INVALID" \
261 : (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) \
262 ? "DBUS_MESSAGE_TYPE_METHOD_CALL" \
263 : (mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) \
264 ? "DBUS_MESSAGE_TYPE_METHOD_RETURN" \
265 : (mtype == DBUS_MESSAGE_TYPE_ERROR) \
266 ? "DBUS_MESSAGE_TYPE_ERROR" \
267 : "DBUS_MESSAGE_TYPE_SIGNAL")
269 /* Transform the object to its string representation for debug
271 #define XD_OBJECT_TO_STRING(object) \
272 SDATA (format2 ("%s", object, Qnil))
274 #define XD_DBUS_VALIDATE_BUS_ADDRESS(bus) \
276 char const *session_bus_address = getenv ("DBUS_SESSION_BUS_ADDRESS"); \
279 DBusAddressEntry **entries; \
282 dbus_error_init (&derror); \
283 if (!dbus_parse_address (SSDATA (bus), &entries, &len, &derror)) \
286 dbus_error_free (&derror); \
287 dbus_address_entries_free (entries); \
288 /* Canonicalize session bus address. */ \
289 if ((session_bus_address != NULL) \
290 && (!NILP (Fstring_equal \
291 (bus, build_string (session_bus_address))))) \
292 bus = QCdbus_session_bus; \
297 CHECK_SYMBOL (bus); \
298 if (!(EQ (bus, QCdbus_system_bus) || EQ (bus, QCdbus_session_bus))) \
299 XD_SIGNAL2 (build_string ("Wrong bus name"), bus); \
300 /* We do not want to have an autolaunch for the session bus. */ \
301 if (EQ (bus, QCdbus_session_bus) && session_bus_address == NULL) \
302 XD_SIGNAL2 (build_string ("No connection to bus"), bus); \
306 #if (HAVE_DBUS_VALIDATE_BUS_NAME || HAVE_DBUS_VALIDATE_PATH \
307 || HAVE_DBUS_VALIDATE_INTERFACE || HAVE_DBUS_VALIDATE_MEMBER)
308 #define XD_DBUS_VALIDATE_OBJECT(object, func) \
310 if (!NILP (object)) \
313 CHECK_STRING (object); \
314 dbus_error_init (&derror); \
315 if (!func (SSDATA (object), &derror)) \
318 dbus_error_free (&derror); \
323 #if HAVE_DBUS_VALIDATE_BUS_NAME
324 #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \
325 XD_DBUS_VALIDATE_OBJECT(bus_name, dbus_validate_bus_name);
327 #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \
328 if (!NILP (bus_name)) CHECK_STRING (bus_name);
331 #if HAVE_DBUS_VALIDATE_PATH
332 #define XD_DBUS_VALIDATE_PATH(path) \
333 XD_DBUS_VALIDATE_OBJECT(path, dbus_validate_path);
335 #define XD_DBUS_VALIDATE_PATH(path) \
336 if (!NILP (path)) CHECK_STRING (path);
339 #if HAVE_DBUS_VALIDATE_INTERFACE
340 #define XD_DBUS_VALIDATE_INTERFACE(interface) \
341 XD_DBUS_VALIDATE_OBJECT(interface, dbus_validate_interface);
343 #define XD_DBUS_VALIDATE_INTERFACE(interface) \
344 if (!NILP (interface)) CHECK_STRING (interface);
347 #if HAVE_DBUS_VALIDATE_MEMBER
348 #define XD_DBUS_VALIDATE_MEMBER(member) \
349 XD_DBUS_VALIDATE_OBJECT(member, dbus_validate_member);
351 #define XD_DBUS_VALIDATE_MEMBER(member) \
352 if (!NILP (member)) CHECK_STRING (member);
355 /* Append to SIGNATURE a copy of X, making sure SIGNATURE does
356 not become too long. */
358 xd_signature_cat (char *signature
, char const *x
)
360 ptrdiff_t siglen
= strlen (signature
);
361 ptrdiff_t xlen
= strlen (x
);
362 if (DBUS_MAXIMUM_SIGNATURE_LENGTH
- xlen
<= siglen
)
364 strcat (signature
, x
);
367 /* Compute SIGNATURE of OBJECT. It must have a form that it can be
368 used in dbus_message_iter_open_container. DTYPE is the DBusType
369 the object is related to. It is passed as argument, because it
370 cannot be detected in basic type objects, when they are preceded by
371 a type symbol. PARENT_TYPE is the DBusType of a container this
372 signature is embedded, or DBUS_TYPE_INVALID. It is needed for the
373 check that DBUS_TYPE_DICT_ENTRY occurs only as array element. */
375 xd_signature (char *signature
, int dtype
, int parent_type
, Lisp_Object object
)
381 char x
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
388 case DBUS_TYPE_UINT16
:
389 CHECK_NATNUM (object
);
390 sprintf (signature
, "%c", dtype
);
393 case DBUS_TYPE_BOOLEAN
:
394 if (!EQ (object
, Qt
) && !EQ (object
, Qnil
))
395 wrong_type_argument (intern ("booleanp"), object
);
396 sprintf (signature
, "%c", dtype
);
399 case DBUS_TYPE_INT16
:
400 CHECK_NUMBER (object
);
401 sprintf (signature
, "%c", dtype
);
404 case DBUS_TYPE_UINT32
:
405 case DBUS_TYPE_UINT64
:
406 #ifdef DBUS_TYPE_UNIX_FD
407 case DBUS_TYPE_UNIX_FD
:
409 case DBUS_TYPE_INT32
:
410 case DBUS_TYPE_INT64
:
411 case DBUS_TYPE_DOUBLE
:
412 CHECK_NUMBER_OR_FLOAT (object
);
413 sprintf (signature
, "%c", dtype
);
416 case DBUS_TYPE_STRING
:
417 case DBUS_TYPE_OBJECT_PATH
:
418 case DBUS_TYPE_SIGNATURE
:
419 CHECK_STRING (object
);
420 sprintf (signature
, "%c", dtype
);
423 case DBUS_TYPE_ARRAY
:
424 /* Check that all list elements have the same D-Bus type. For
425 complex element types, we just check the container type, not
426 the whole element's signature. */
429 /* Type symbol is optional. */
430 if (EQ (QCdbus_type_array
, CAR_SAFE (elt
)))
431 elt
= XD_NEXT_VALUE (elt
);
433 /* If the array is empty, DBUS_TYPE_STRING is the default
437 subtype
= DBUS_TYPE_STRING
;
438 subsig
= DBUS_TYPE_STRING_AS_STRING
;
442 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
443 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
447 /* If the element type is DBUS_TYPE_SIGNATURE, and this is the
448 only element, the value of this element is used as the
449 array's element signature. */
450 if ((subtype
== DBUS_TYPE_SIGNATURE
)
451 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt
)))
452 && NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
453 subsig
= SSDATA (CAR_SAFE (XD_NEXT_VALUE (elt
)));
457 if (subtype
!= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
)))
458 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (elt
));
459 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
462 subsiglen
= snprintf (signature
, DBUS_MAXIMUM_SIGNATURE_LENGTH
,
463 "%c%s", dtype
, subsig
);
464 if (! (0 <= subsiglen
&& subsiglen
< DBUS_MAXIMUM_SIGNATURE_LENGTH
))
468 case DBUS_TYPE_VARIANT
:
469 /* Check that there is exactly one list element. */
472 elt
= XD_NEXT_VALUE (elt
);
473 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
474 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
476 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
477 wrong_type_argument (intern ("D-Bus"),
478 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt
))));
480 sprintf (signature
, "%c", dtype
);
483 case DBUS_TYPE_STRUCT
:
484 /* A struct list might contain any number of elements with
485 different types. No further check needed. */
488 elt
= XD_NEXT_VALUE (elt
);
490 /* Compose the signature from the elements. It is enclosed by
492 sprintf (signature
, "%c", DBUS_STRUCT_BEGIN_CHAR
);
495 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
496 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
497 xd_signature_cat (signature
, x
);
498 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
500 xd_signature_cat (signature
, DBUS_STRUCT_END_CHAR_AS_STRING
);
503 case DBUS_TYPE_DICT_ENTRY
:
504 /* Check that there are exactly two list elements, and the first
505 one is of basic type. The dictionary entry itself must be an
506 element of an array. */
509 /* Check the parent object type. */
510 if (parent_type
!= DBUS_TYPE_ARRAY
)
511 wrong_type_argument (intern ("D-Bus"), object
);
513 /* Compose the signature from the elements. It is enclosed by
515 sprintf (signature
, "%c", DBUS_DICT_ENTRY_BEGIN_CHAR
);
518 elt
= XD_NEXT_VALUE (elt
);
519 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
520 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
521 xd_signature_cat (signature
, x
);
523 if (!XD_BASIC_DBUS_TYPE (subtype
))
524 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt
)));
526 /* Second element. */
527 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
528 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
529 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
530 xd_signature_cat (signature
, x
);
532 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
533 wrong_type_argument (intern ("D-Bus"),
534 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt
))));
536 /* Closing signature. */
537 xd_signature_cat (signature
, DBUS_DICT_ENTRY_END_CHAR_AS_STRING
);
541 wrong_type_argument (intern ("D-Bus"), object
);
544 XD_DEBUG_MESSAGE ("%s", signature
);
547 /* Convert X to a signed integer with bounds LO and HI. */
549 xd_extract_signed (Lisp_Object x
, intmax_t lo
, intmax_t hi
)
551 CHECK_NUMBER_OR_FLOAT (x
);
554 if (lo
<= XINT (x
) && XINT (x
) <= hi
)
559 double d
= XFLOAT_DATA (x
);
560 if (lo
<= d
&& d
<= hi
)
567 if (xd_in_read_queued_messages
)
568 Fthrow (Qdbus_error
, Qnil
);
570 args_out_of_range_3 (x
,
571 make_fixnum_or_float (lo
),
572 make_fixnum_or_float (hi
));
575 /* Convert X to an unsigned integer with bounds 0 and HI. */
577 xd_extract_unsigned (Lisp_Object x
, uintmax_t hi
)
579 CHECK_NUMBER_OR_FLOAT (x
);
582 if (0 <= XINT (x
) && XINT (x
) <= hi
)
587 double d
= XFLOAT_DATA (x
);
588 if (0 <= d
&& d
<= hi
)
595 if (xd_in_read_queued_messages
)
596 Fthrow (Qdbus_error
, Qnil
);
598 args_out_of_range_3 (x
, make_number (0), make_fixnum_or_float (hi
));
601 /* Append C value, extracted from Lisp OBJECT, to iteration ITER.
602 DTYPE must be a valid DBusType. It is used to convert Lisp
603 objects, being arguments of `dbus-call-method' or
604 `dbus-send-signal', into corresponding C values appended as
605 arguments to a D-Bus message. */
607 xd_append_arg (int dtype
, Lisp_Object object
, DBusMessageIter
*iter
)
609 char signature
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
610 DBusMessageIter subiter
;
612 if (XD_BASIC_DBUS_TYPE (dtype
))
616 CHECK_NATNUM (object
);
618 unsigned char val
= XFASTINT (object
) & 0xFF;
619 XD_DEBUG_MESSAGE ("%c %u", dtype
, val
);
620 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
621 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
625 case DBUS_TYPE_BOOLEAN
:
627 dbus_bool_t val
= (NILP (object
)) ? FALSE
: TRUE
;
628 XD_DEBUG_MESSAGE ("%c %s", dtype
, (val
== FALSE
) ? "false" : "true");
629 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
630 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
634 case DBUS_TYPE_INT16
:
637 xd_extract_signed (object
,
638 TYPE_MINIMUM (dbus_int16_t
),
639 TYPE_MAXIMUM (dbus_int16_t
));
641 XD_DEBUG_MESSAGE ("%c %d", dtype
, pval
);
642 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
643 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
647 case DBUS_TYPE_UINT16
:
650 xd_extract_unsigned (object
,
651 TYPE_MAXIMUM (dbus_uint16_t
));
652 unsigned int pval
= val
;
653 XD_DEBUG_MESSAGE ("%c %u", dtype
, pval
);
654 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
655 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
659 case DBUS_TYPE_INT32
:
662 xd_extract_signed (object
,
663 TYPE_MINIMUM (dbus_int32_t
),
664 TYPE_MAXIMUM (dbus_int32_t
));
666 XD_DEBUG_MESSAGE ("%c %d", dtype
, pval
);
667 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
668 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
672 case DBUS_TYPE_UINT32
:
673 #ifdef DBUS_TYPE_UNIX_FD
674 case DBUS_TYPE_UNIX_FD
:
678 xd_extract_unsigned (object
,
679 TYPE_MAXIMUM (dbus_uint32_t
));
680 unsigned int pval
= val
;
681 XD_DEBUG_MESSAGE ("%c %u", dtype
, pval
);
682 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
683 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
687 case DBUS_TYPE_INT64
:
690 xd_extract_signed (object
,
691 TYPE_MINIMUM (dbus_int64_t
),
692 TYPE_MAXIMUM (dbus_int64_t
));
693 printmax_t pval
= val
;
694 XD_DEBUG_MESSAGE ("%c %"pMd
, dtype
, pval
);
695 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
696 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
700 case DBUS_TYPE_UINT64
:
703 xd_extract_unsigned (object
,
704 TYPE_MAXIMUM (dbus_uint64_t
));
705 uprintmax_t pval
= val
;
706 XD_DEBUG_MESSAGE ("%c %"pMu
, dtype
, pval
);
707 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
708 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
712 case DBUS_TYPE_DOUBLE
:
714 double val
= extract_float (object
);
715 XD_DEBUG_MESSAGE ("%c %f", dtype
, val
);
716 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
717 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
721 case DBUS_TYPE_STRING
:
722 case DBUS_TYPE_OBJECT_PATH
:
723 case DBUS_TYPE_SIGNATURE
:
724 CHECK_STRING (object
);
726 /* We need to send a valid UTF-8 string. We could encode `object'
727 but by not encoding it, we guarantee it's valid utf-8, even if
728 it contains eight-bit-bytes. Of course, you can still send
729 manually-crafted junk by passing a unibyte string. */
730 char *val
= SSDATA (object
);
731 XD_DEBUG_MESSAGE ("%c %s", dtype
, val
);
732 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
733 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
738 else /* Compound types. */
741 /* All compound types except array have a type symbol. For
742 array, it is optional. Skip it. */
743 if (!XD_BASIC_DBUS_TYPE (XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
))))
744 object
= XD_NEXT_VALUE (object
);
746 /* Open new subiteration. */
749 case DBUS_TYPE_ARRAY
:
750 /* An array has only elements of the same type. So it is
751 sufficient to check the first element's signature
755 /* If the array is empty, DBUS_TYPE_STRING is the default
757 strcpy (signature
, DBUS_TYPE_STRING_AS_STRING
);
760 /* If the element type is DBUS_TYPE_SIGNATURE, and this is
761 the only element, the value of this element is used as
762 the array's element signature. */
763 if ((XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
))
764 == DBUS_TYPE_SIGNATURE
)
765 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object
)))
766 && NILP (CDR_SAFE (XD_NEXT_VALUE (object
))))
768 strcpy (signature
, SSDATA (CAR_SAFE (XD_NEXT_VALUE (object
))));
769 object
= CDR_SAFE (XD_NEXT_VALUE (object
));
773 xd_signature (signature
,
774 XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
)),
775 dtype
, CAR_SAFE (XD_NEXT_VALUE (object
)));
777 XD_DEBUG_MESSAGE ("%c %s %s", dtype
, signature
,
778 XD_OBJECT_TO_STRING (object
));
779 if (!dbus_message_iter_open_container (iter
, dtype
,
780 signature
, &subiter
))
781 XD_SIGNAL3 (build_string ("Cannot open container"),
782 make_number (dtype
), build_string (signature
));
785 case DBUS_TYPE_VARIANT
:
786 /* A variant has just one element. */
787 xd_signature (signature
, XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
)),
788 dtype
, CAR_SAFE (XD_NEXT_VALUE (object
)));
790 XD_DEBUG_MESSAGE ("%c %s %s", dtype
, signature
,
791 XD_OBJECT_TO_STRING (object
));
792 if (!dbus_message_iter_open_container (iter
, dtype
,
793 signature
, &subiter
))
794 XD_SIGNAL3 (build_string ("Cannot open container"),
795 make_number (dtype
), build_string (signature
));
798 case DBUS_TYPE_STRUCT
:
799 case DBUS_TYPE_DICT_ENTRY
:
800 /* These containers do not require a signature. */
801 XD_DEBUG_MESSAGE ("%c %s", dtype
, XD_OBJECT_TO_STRING (object
));
802 if (!dbus_message_iter_open_container (iter
, dtype
, NULL
, &subiter
))
803 XD_SIGNAL2 (build_string ("Cannot open container"),
804 make_number (dtype
));
808 /* Loop over list elements. */
809 while (!NILP (object
))
811 dtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
));
812 object
= XD_NEXT_VALUE (object
);
814 xd_append_arg (dtype
, CAR_SAFE (object
), &subiter
);
816 object
= CDR_SAFE (object
);
819 /* Close the subiteration. */
820 if (!dbus_message_iter_close_container (iter
, &subiter
))
821 XD_SIGNAL2 (build_string ("Cannot close container"),
822 make_number (dtype
));
826 /* Retrieve C value from a DBusMessageIter structure ITER, and return
827 a converted Lisp object. The type DTYPE of the argument of the
828 D-Bus message must be a valid DBusType. Compound D-Bus types
829 result always in a Lisp list. */
831 xd_retrieve_arg (int dtype
, DBusMessageIter
*iter
)
839 dbus_message_iter_get_basic (iter
, &val
);
841 XD_DEBUG_MESSAGE ("%c %u", dtype
, val
);
842 return make_number (val
);
845 case DBUS_TYPE_BOOLEAN
:
848 dbus_message_iter_get_basic (iter
, &val
);
849 XD_DEBUG_MESSAGE ("%c %s", dtype
, (val
== FALSE
) ? "false" : "true");
850 return (val
== FALSE
) ? Qnil
: Qt
;
853 case DBUS_TYPE_INT16
:
857 dbus_message_iter_get_basic (iter
, &val
);
859 XD_DEBUG_MESSAGE ("%c %d", dtype
, pval
);
860 return make_number (val
);
863 case DBUS_TYPE_UINT16
:
867 dbus_message_iter_get_basic (iter
, &val
);
869 XD_DEBUG_MESSAGE ("%c %d", dtype
, pval
);
870 return make_number (val
);
873 case DBUS_TYPE_INT32
:
877 dbus_message_iter_get_basic (iter
, &val
);
879 XD_DEBUG_MESSAGE ("%c %d", dtype
, pval
);
880 return make_fixnum_or_float (val
);
883 case DBUS_TYPE_UINT32
:
884 #ifdef DBUS_TYPE_UNIX_FD
885 case DBUS_TYPE_UNIX_FD
:
890 dbus_message_iter_get_basic (iter
, &val
);
892 XD_DEBUG_MESSAGE ("%c %u", dtype
, pval
);
893 return make_fixnum_or_float (val
);
896 case DBUS_TYPE_INT64
:
900 dbus_message_iter_get_basic (iter
, &val
);
902 XD_DEBUG_MESSAGE ("%c %"pMd
, dtype
, pval
);
903 return make_fixnum_or_float (val
);
906 case DBUS_TYPE_UINT64
:
910 dbus_message_iter_get_basic (iter
, &val
);
912 XD_DEBUG_MESSAGE ("%c %"pMd
, dtype
, pval
);
913 return make_fixnum_or_float (val
);
916 case DBUS_TYPE_DOUBLE
:
919 dbus_message_iter_get_basic (iter
, &val
);
920 XD_DEBUG_MESSAGE ("%c %f", dtype
, val
);
921 return make_float (val
);
924 case DBUS_TYPE_STRING
:
925 case DBUS_TYPE_OBJECT_PATH
:
926 case DBUS_TYPE_SIGNATURE
:
929 dbus_message_iter_get_basic (iter
, &val
);
930 XD_DEBUG_MESSAGE ("%c %s", dtype
, val
);
931 return build_string (val
);
934 case DBUS_TYPE_ARRAY
:
935 case DBUS_TYPE_VARIANT
:
936 case DBUS_TYPE_STRUCT
:
937 case DBUS_TYPE_DICT_ENTRY
:
941 DBusMessageIter subiter
;
945 dbus_message_iter_recurse (iter
, &subiter
);
946 while ((subtype
= dbus_message_iter_get_arg_type (&subiter
))
947 != DBUS_TYPE_INVALID
)
949 result
= Fcons (xd_retrieve_arg (subtype
, &subiter
), result
);
950 dbus_message_iter_next (&subiter
);
952 XD_DEBUG_MESSAGE ("%c %s", dtype
, XD_OBJECT_TO_STRING (result
));
953 RETURN_UNGCPRO (Fnreverse (result
));
957 XD_DEBUG_MESSAGE ("DBusType '%c' not supported", dtype
);
962 /* Return the number of references of the shared CONNECTION. */
964 xd_get_connection_references (DBusConnection
*connection
)
968 /* We cannot access the DBusConnection structure, it is not public.
969 But we know, that the reference counter is the first field in
971 refcount
= (void *) &connection
;
972 refcount
= (void *) *refcount
;
976 /* Convert a Lisp D-Bus object to a pointer. */
977 static DBusConnection
*
978 xd_lisp_dbus_to_dbus (Lisp_Object bus
)
980 return (DBusConnection
*) (intptr_t) XFASTINT (bus
);
983 /* Return D-Bus connection address. BUS is either a Lisp symbol,
984 :system or :session, or a string denoting the bus address. */
985 static DBusConnection
*
986 xd_get_connection_address (Lisp_Object bus
)
988 DBusConnection
*connection
;
991 val
= CDR_SAFE (Fassoc (bus
, xd_registered_buses
));
993 XD_SIGNAL2 (build_string ("No connection to bus"), bus
);
995 connection
= xd_lisp_dbus_to_dbus (val
);
997 if (!dbus_connection_get_is_connected (connection
))
998 XD_SIGNAL2 (build_string ("No connection to bus"), bus
);
1003 /* Return the file descriptor for WATCH, -1 if not found. */
1005 xd_find_watch_fd (DBusWatch
*watch
)
1007 #if HAVE_DBUS_WATCH_GET_UNIX_FD
1008 /* TODO: Reverse these on w32, which prefers the opposite. */
1009 int fd
= dbus_watch_get_unix_fd (watch
);
1011 fd
= dbus_watch_get_socket (watch
);
1013 int fd
= dbus_watch_get_fd (watch
);
1019 static void xd_read_queued_messages (int fd
, void *data
);
1021 /* Start monitoring WATCH for possible I/O. */
1023 xd_add_watch (DBusWatch
*watch
, void *data
)
1025 unsigned int flags
= dbus_watch_get_flags (watch
);
1026 int fd
= xd_find_watch_fd (watch
);
1028 XD_DEBUG_MESSAGE ("fd %d, write %d, enabled %d",
1029 fd
, flags
& DBUS_WATCH_WRITABLE
,
1030 dbus_watch_get_enabled (watch
));
1035 if (dbus_watch_get_enabled (watch
))
1037 if (flags
& DBUS_WATCH_WRITABLE
)
1038 add_write_fd (fd
, xd_read_queued_messages
, data
);
1039 if (flags
& DBUS_WATCH_READABLE
)
1040 add_read_fd (fd
, xd_read_queued_messages
, data
);
1045 /* Stop monitoring WATCH for possible I/O.
1046 DATA is the used bus, either a string or QCdbus_system_bus or
1047 QCdbus_session_bus. */
1049 xd_remove_watch (DBusWatch
*watch
, void *data
)
1051 unsigned int flags
= dbus_watch_get_flags (watch
);
1052 int fd
= xd_find_watch_fd (watch
);
1054 XD_DEBUG_MESSAGE ("fd %d", fd
);
1059 /* Unset session environment. */
1061 if (XSYMBOL (QCdbus_session_bus
) == data
)
1063 XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
1064 unsetenv ("DBUS_SESSION_BUS_ADDRESS");
1068 if (flags
& DBUS_WATCH_WRITABLE
)
1069 delete_write_fd (fd
);
1070 if (flags
& DBUS_WATCH_READABLE
)
1071 delete_read_fd (fd
);
1074 /* Toggle monitoring WATCH for possible I/O. */
1076 xd_toggle_watch (DBusWatch
*watch
, void *data
)
1078 if (dbus_watch_get_enabled (watch
))
1079 xd_add_watch (watch
, data
);
1081 xd_remove_watch (watch
, data
);
1084 /* Close connection to D-Bus BUS. */
1086 xd_close_bus (Lisp_Object bus
)
1088 DBusConnection
*connection
;
1092 /* Check whether we are connected. */
1093 val
= Fassoc (bus
, xd_registered_buses
);
1097 busobj
= CDR_SAFE(val
);
1098 if (NILP (busobj
)) {
1099 xd_registered_buses
= Fdelete (val
, xd_registered_buses
);
1103 /* Retrieve bus address. */
1104 connection
= xd_lisp_dbus_to_dbus (busobj
);
1106 if (xd_get_connection_references (connection
) == 1)
1108 /* Close connection, if there isn't another shared application. */
1109 XD_DEBUG_MESSAGE ("Close connection to bus %s",
1110 XD_OBJECT_TO_STRING (bus
));
1111 dbus_connection_close (connection
);
1113 xd_registered_buses
= Fdelete (val
, xd_registered_buses
);
1117 /* Decrement reference count. */
1118 dbus_connection_unref (connection
);
1124 DEFUN ("dbus-init-bus", Fdbus_init_bus
, Sdbus_init_bus
, 1, 2, 0,
1125 doc
: /* Establish the connection to D-Bus BUS.
1127 BUS can be either the symbol `:system' or the symbol `:session', or it
1128 can be a string denoting the address of the corresponding bus. For
1129 the system and session buses, this function is called when loading
1130 `dbus.el', there is no need to call it again.
1132 The function returns a number, which counts the connections this Emacs
1133 session has established to the BUS under the same unique name (see
1134 `dbus-get-unique-name'). It depends on the libraries Emacs is linked
1135 with, and on the environment Emacs is running. For example, if Emacs
1136 is linked with the gtk toolkit, and it runs in a GTK-aware environment
1137 like Gnome, another connection might already be established.
1139 When PRIVATE is non-nil, a new connection is established instead of
1140 reusing an existing one. It results in a new unique name at the bus.
1141 This can be used, if it is necessary to distinguish from another
1142 connection used in the same Emacs process, like the one established by
1143 GTK+. It should be used with care for at least the `:system' and
1144 `:session' buses, because other Emacs Lisp packages might already use
1145 this connection to those buses. */)
1146 (Lisp_Object bus
, Lisp_Object
private)
1148 DBusConnection
*connection
;
1153 /* Check parameter. */
1154 XD_DBUS_VALIDATE_BUS_ADDRESS (bus
);
1156 /* Close bus if it is already open. */
1159 /* Check, whether we are still connected. */
1160 val
= Fassoc (bus
, xd_registered_buses
);
1163 connection
= xd_get_connection_address (bus
);
1164 dbus_connection_ref (connection
);
1170 dbus_error_init (&derror
);
1172 /* Open the connection. */
1175 connection
= dbus_connection_open (SSDATA (bus
), &derror
);
1177 connection
= dbus_connection_open_private (SSDATA (bus
), &derror
);
1181 connection
= dbus_bus_get (EQ (bus
, QCdbus_system_bus
)
1182 ? DBUS_BUS_SYSTEM
: DBUS_BUS_SESSION
,
1185 connection
= dbus_bus_get_private (EQ (bus
, QCdbus_system_bus
)
1186 ? DBUS_BUS_SYSTEM
: DBUS_BUS_SESSION
,
1189 if (dbus_error_is_set (&derror
))
1192 if (connection
== NULL
)
1193 XD_SIGNAL2 (build_string ("No connection to bus"), bus
);
1195 /* If it is not the system or session bus, we must register
1196 ourselves. Otherwise, we have called dbus_bus_get, which has
1197 configured us to exit if the connection closes - we undo this
1200 dbus_bus_register (connection
, &derror
);
1202 dbus_connection_set_exit_on_disconnect (connection
, FALSE
);
1204 if (dbus_error_is_set (&derror
))
1207 /* Add the watch functions. We pass also the bus as data, in
1208 order to distinguish between the buses in xd_remove_watch. */
1209 if (!dbus_connection_set_watch_functions (connection
,
1214 ? (void *) XSYMBOL (bus
)
1215 : (void *) XSTRING (bus
),
1217 XD_SIGNAL1 (build_string ("Cannot add watch functions"));
1219 /* Add bus to list of registered buses. */
1220 XSETFASTINT (val
, (intptr_t) connection
);
1221 xd_registered_buses
= Fcons (Fcons (bus
, val
), xd_registered_buses
);
1223 /* We do not want to abort. */
1224 xputenv ("DBUS_FATAL_WARNINGS=0");
1227 dbus_error_free (&derror
);
1230 /* Return reference counter. */
1231 refcount
= xd_get_connection_references (connection
);
1232 XD_DEBUG_MESSAGE ("Bus %s, Reference counter %"pD
"d",
1233 XD_OBJECT_TO_STRING (bus
), refcount
);
1234 return make_number (refcount
);
1237 DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name
, Sdbus_get_unique_name
,
1239 doc
: /* Return the unique name of Emacs registered at D-Bus BUS. */)
1242 DBusConnection
*connection
;
1245 /* Check parameter. */
1246 XD_DBUS_VALIDATE_BUS_ADDRESS (bus
);
1248 /* Retrieve bus address. */
1249 connection
= xd_get_connection_address (bus
);
1251 /* Request the name. */
1252 name
= dbus_bus_get_unique_name (connection
);
1254 XD_SIGNAL1 (build_string ("No unique name available"));
1257 return build_string (name
);
1260 DEFUN ("dbus-message-internal", Fdbus_message_internal
, Sdbus_message_internal
,
1262 doc
: /* Send a D-Bus message.
1263 This is an internal function, it shall not be used outside dbus.el.
1265 The following usages are expected:
1267 `dbus-call-method', `dbus-call-method-asynchronously':
1268 \(dbus-message-internal
1269 dbus-message-type-method-call BUS SERVICE PATH INTERFACE METHOD HANDLER
1270 &optional :timeout TIMEOUT &rest ARGS)
1273 \(dbus-message-internal
1274 dbus-message-type-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS)
1276 `dbus-method-return-internal':
1277 \(dbus-message-internal
1278 dbus-message-type-method-return BUS SERVICE SERIAL &rest ARGS)
1280 `dbus-method-error-internal':
1281 \(dbus-message-internal
1282 dbus-message-type-error BUS SERVICE SERIAL &rest ARGS)
1284 usage: (dbus-message-internal &rest REST) */)
1285 (ptrdiff_t nargs
, Lisp_Object
*args
)
1287 Lisp_Object message_type
, bus
, service
, handler
;
1288 Lisp_Object path
= Qnil
;
1289 Lisp_Object interface
= Qnil
;
1290 Lisp_Object member
= Qnil
;
1292 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
1293 DBusConnection
*connection
;
1294 DBusMessage
*dmessage
;
1295 DBusMessageIter iter
;
1298 dbus_uint32_t serial
= 0;
1299 unsigned int ui_serial
;
1302 char signature
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
1304 /* Initialize parameters. */
1305 message_type
= args
[0];
1310 CHECK_NATNUM (message_type
);
1311 if (! (DBUS_MESSAGE_TYPE_INVALID
< XFASTINT (message_type
)
1312 && XFASTINT (message_type
) < DBUS_NUM_MESSAGE_TYPES
))
1313 XD_SIGNAL2 (build_string ("Invalid message type"), message_type
);
1314 mtype
= XFASTINT (message_type
);
1316 if ((mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1317 || (mtype
== DBUS_MESSAGE_TYPE_SIGNAL
))
1320 interface
= args
[4];
1322 if (mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1324 count
= (mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
) ? 7 : 6;
1326 else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1328 serial
= xd_extract_unsigned (args
[3], TYPE_MAXIMUM (dbus_uint32_t
));
1332 /* Check parameters. */
1333 XD_DBUS_VALIDATE_BUS_ADDRESS (bus
);
1334 XD_DBUS_VALIDATE_BUS_NAME (service
);
1336 xsignal2 (Qwrong_number_of_arguments
,
1337 Qdbus_message_internal
,
1338 make_number (nargs
));
1340 if ((mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1341 || (mtype
== DBUS_MESSAGE_TYPE_SIGNAL
))
1343 XD_DBUS_VALIDATE_PATH (path
);
1344 XD_DBUS_VALIDATE_INTERFACE (interface
);
1345 XD_DBUS_VALIDATE_MEMBER (member
);
1346 if (!NILP (handler
) && (!FUNCTIONP (handler
)))
1347 wrong_type_argument (Qinvalid_function
, handler
);
1350 /* Protect Lisp variables. */
1351 GCPRO6 (bus
, service
, path
, interface
, member
, handler
);
1353 /* Trace parameters. */
1356 case DBUS_MESSAGE_TYPE_METHOD_CALL
:
1357 XD_DEBUG_MESSAGE ("%s %s %s %s %s %s %s",
1358 XD_MESSAGE_TYPE_TO_STRING (mtype
),
1359 XD_OBJECT_TO_STRING (bus
),
1360 XD_OBJECT_TO_STRING (service
),
1361 XD_OBJECT_TO_STRING (path
),
1362 XD_OBJECT_TO_STRING (interface
),
1363 XD_OBJECT_TO_STRING (member
),
1364 XD_OBJECT_TO_STRING (handler
));
1366 case DBUS_MESSAGE_TYPE_SIGNAL
:
1367 XD_DEBUG_MESSAGE ("%s %s %s %s %s %s",
1368 XD_MESSAGE_TYPE_TO_STRING (mtype
),
1369 XD_OBJECT_TO_STRING (bus
),
1370 XD_OBJECT_TO_STRING (service
),
1371 XD_OBJECT_TO_STRING (path
),
1372 XD_OBJECT_TO_STRING (interface
),
1373 XD_OBJECT_TO_STRING (member
));
1375 default: /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1377 XD_DEBUG_MESSAGE ("%s %s %s %u",
1378 XD_MESSAGE_TYPE_TO_STRING (mtype
),
1379 XD_OBJECT_TO_STRING (bus
),
1380 XD_OBJECT_TO_STRING (service
),
1384 /* Retrieve bus address. */
1385 connection
= xd_get_connection_address (bus
);
1387 /* Create the D-Bus message. */
1388 dmessage
= dbus_message_new (mtype
);
1389 if (dmessage
== NULL
)
1392 XD_SIGNAL1 (build_string ("Unable to create a new message"));
1395 if (STRINGP (service
))
1397 if (mtype
!= DBUS_MESSAGE_TYPE_SIGNAL
)
1398 /* Set destination. */
1400 if (!dbus_message_set_destination (dmessage
, SSDATA (service
)))
1403 XD_SIGNAL2 (build_string ("Unable to set the destination"),
1409 /* Set destination for unicast signals. */
1413 /* If it is the same unique name as we are registered at the
1414 bus or an unknown name, we regard it as broadcast message
1415 due to backward compatibility. */
1416 if (dbus_bus_name_has_owner (connection
, SSDATA (service
), NULL
))
1417 uname
= call2 (intern ("dbus-get-name-owner"), bus
, service
);
1422 && (strcmp (dbus_bus_get_unique_name (connection
), SSDATA (uname
))
1424 && (!dbus_message_set_destination (dmessage
, SSDATA (service
))))
1427 XD_SIGNAL2 (build_string ("Unable to set signal destination"),
1433 /* Set message parameters. */
1434 if ((mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1435 || (mtype
== DBUS_MESSAGE_TYPE_SIGNAL
))
1437 if ((!dbus_message_set_path (dmessage
, SSDATA (path
)))
1438 || (!dbus_message_set_interface (dmessage
, SSDATA (interface
)))
1439 || (!dbus_message_set_member (dmessage
, SSDATA (member
))))
1442 XD_SIGNAL1 (build_string ("Unable to set the message parameter"));
1446 else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1448 if (!dbus_message_set_reply_serial (dmessage
, serial
))
1451 XD_SIGNAL1 (build_string ("Unable to create a return message"));
1454 if ((mtype
== DBUS_MESSAGE_TYPE_ERROR
)
1455 && (!dbus_message_set_error_name (dmessage
, DBUS_ERROR_FAILED
)))
1458 XD_SIGNAL1 (build_string ("Unable to create a error message"));
1462 /* Check for timeout parameter. */
1463 if ((count
+2 <= nargs
) && (EQ ((args
[count
]), QCdbus_timeout
)))
1465 CHECK_NATNUM (args
[count
+1]);
1466 timeout
= min (XFASTINT (args
[count
+1]), INT_MAX
);
1470 /* Initialize parameter list of message. */
1471 dbus_message_iter_init_append (dmessage
, &iter
);
1473 /* Append parameters to the message. */
1474 for (; count
< nargs
; ++count
)
1476 dtype
= XD_OBJECT_TO_DBUS_TYPE (args
[count
]);
1477 if (XD_DBUS_TYPE_P (args
[count
]))
1479 XD_DEBUG_VALID_LISP_OBJECT_P (args
[count
]);
1480 XD_DEBUG_VALID_LISP_OBJECT_P (args
[count
+1]);
1481 XD_DEBUG_MESSAGE ("Parameter%"pD
"d %s %s", count
- 4,
1482 XD_OBJECT_TO_STRING (args
[count
]),
1483 XD_OBJECT_TO_STRING (args
[count
+1]));
1488 XD_DEBUG_VALID_LISP_OBJECT_P (args
[count
]);
1489 XD_DEBUG_MESSAGE ("Parameter%"pD
"d %s", count
- 4,
1490 XD_OBJECT_TO_STRING (args
[count
]));
1493 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1494 indication that there is no parent type. */
1495 xd_signature (signature
, dtype
, DBUS_TYPE_INVALID
, args
[count
]);
1497 xd_append_arg (dtype
, args
[count
], &iter
);
1500 if (!NILP (handler
))
1502 /* Send the message. The message is just added to the outgoing
1504 if (!dbus_connection_send_with_reply (connection
, dmessage
,
1508 XD_SIGNAL1 (build_string ("Cannot send message"));
1511 /* The result is the key in Vdbus_registered_objects_table. */
1512 serial
= dbus_message_get_serial (dmessage
);
1513 result
= list3 (QCdbus_registered_serial
,
1514 bus
, make_fixnum_or_float (serial
));
1516 /* Create a hash table entry. */
1517 Fputhash (result
, handler
, Vdbus_registered_objects_table
);
1521 /* Send the message. The message is just added to the outgoing
1523 if (!dbus_connection_send (connection
, dmessage
, NULL
))
1526 XD_SIGNAL1 (build_string ("Cannot send message"));
1532 XD_DEBUG_MESSAGE ("Message sent: %s", XD_OBJECT_TO_STRING (result
));
1535 dbus_message_unref (dmessage
);
1537 /* Return the result. */
1538 RETURN_UNGCPRO (result
);
1541 /* Read one queued incoming message of the D-Bus BUS.
1542 BUS is either a Lisp symbol, :system or :session, or a string denoting
1545 xd_read_message_1 (DBusConnection
*connection
, Lisp_Object bus
)
1547 Lisp_Object args
, key
, value
;
1548 struct gcpro gcpro1
;
1549 struct input_event event
;
1550 DBusMessage
*dmessage
;
1551 DBusMessageIter iter
;
1554 dbus_uint32_t serial
;
1555 unsigned int ui_serial
;
1556 const char *uname
, *path
, *interface
, *member
;
1558 dmessage
= dbus_connection_pop_message (connection
);
1560 /* Return if there is no queued message. */
1561 if (dmessage
== NULL
)
1564 /* Collect the parameters. */
1568 /* Loop over the resulting parameters. Construct a list. */
1569 if (dbus_message_iter_init (dmessage
, &iter
))
1571 while ((dtype
= dbus_message_iter_get_arg_type (&iter
))
1572 != DBUS_TYPE_INVALID
)
1574 args
= Fcons (xd_retrieve_arg (dtype
, &iter
), args
);
1575 dbus_message_iter_next (&iter
);
1577 /* The arguments are stored in reverse order. Reorder them. */
1578 args
= Fnreverse (args
);
1581 /* Read message type, message serial, unique name, object path,
1582 interface and member from the message. */
1583 mtype
= dbus_message_get_type (dmessage
);
1584 ui_serial
= serial
=
1585 ((mtype
== DBUS_MESSAGE_TYPE_METHOD_RETURN
)
1586 || (mtype
== DBUS_MESSAGE_TYPE_ERROR
))
1587 ? dbus_message_get_reply_serial (dmessage
)
1588 : dbus_message_get_serial (dmessage
);
1589 uname
= dbus_message_get_sender (dmessage
);
1590 path
= dbus_message_get_path (dmessage
);
1591 interface
= dbus_message_get_interface (dmessage
);
1592 member
= dbus_message_get_member (dmessage
);
1594 XD_DEBUG_MESSAGE ("Event received: %s %u %s %s %s %s %s",
1595 XD_MESSAGE_TYPE_TO_STRING (mtype
),
1596 ui_serial
, uname
, path
, interface
, member
,
1597 XD_OBJECT_TO_STRING (args
));
1599 if (mtype
== DBUS_MESSAGE_TYPE_INVALID
)
1602 else if ((mtype
== DBUS_MESSAGE_TYPE_METHOD_RETURN
)
1603 || (mtype
== DBUS_MESSAGE_TYPE_ERROR
))
1605 /* Search for a registered function of the message. */
1606 key
= list3 (QCdbus_registered_serial
, bus
,
1607 make_fixnum_or_float (serial
));
1608 value
= Fgethash (key
, Vdbus_registered_objects_table
, Qnil
);
1610 /* There shall be exactly one entry. Construct an event. */
1614 /* Remove the entry. */
1615 Fremhash (key
, Vdbus_registered_objects_table
);
1617 /* Construct an event. */
1619 event
.kind
= DBUS_EVENT
;
1620 event
.frame_or_window
= Qnil
;
1621 event
.arg
= Fcons (value
, args
);
1624 else /* DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_SIGNAL. */
1626 /* Vdbus_registered_objects_table requires non-nil interface and
1628 if ((interface
== NULL
) || (member
== NULL
))
1631 /* Search for a registered function of the message. */
1632 key
= list4 ((mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1633 ? QCdbus_registered_method
1634 : QCdbus_registered_signal
,
1635 bus
, build_string (interface
), build_string (member
));
1636 value
= Fgethash (key
, Vdbus_registered_objects_table
, Qnil
);
1638 /* Loop over the registered functions. Construct an event. */
1639 while (!NILP (value
))
1641 key
= CAR_SAFE (value
);
1642 /* key has the structure (UNAME SERVICE PATH HANDLER). */
1643 if (((uname
== NULL
)
1644 || (NILP (CAR_SAFE (key
)))
1645 || (strcmp (uname
, SSDATA (CAR_SAFE (key
))) == 0))
1647 || (NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))
1649 SSDATA (CAR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))
1651 && (!NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))))
1654 event
.kind
= DBUS_EVENT
;
1655 event
.frame_or_window
= Qnil
;
1657 = Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key
)))), args
);
1660 value
= CDR_SAFE (value
);
1667 /* Add type, serial, uname, path, interface and member to the event. */
1668 event
.arg
= Fcons ((member
== NULL
? Qnil
: build_string (member
)),
1670 event
.arg
= Fcons ((interface
== NULL
? Qnil
: build_string (interface
)),
1672 event
.arg
= Fcons ((path
== NULL
? Qnil
: build_string (path
)),
1674 event
.arg
= Fcons ((uname
== NULL
? Qnil
: build_string (uname
)),
1676 event
.arg
= Fcons (make_fixnum_or_float (serial
), event
.arg
);
1677 event
.arg
= Fcons (make_number (mtype
), event
.arg
);
1679 /* Add the bus symbol to the event. */
1680 event
.arg
= Fcons (bus
, event
.arg
);
1682 /* Store it into the input event queue. */
1683 kbd_buffer_store_event (&event
);
1685 XD_DEBUG_MESSAGE ("Event stored: %s", XD_OBJECT_TO_STRING (event
.arg
));
1689 dbus_message_unref (dmessage
);
1694 /* Read queued incoming messages of the D-Bus BUS.
1695 BUS is either a Lisp symbol, :system or :session, or a string denoting
1698 xd_read_message (Lisp_Object bus
)
1700 /* Retrieve bus address. */
1701 DBusConnection
*connection
= xd_get_connection_address (bus
);
1703 /* Non blocking read of the next available message. */
1704 dbus_connection_read_write (connection
, 0);
1706 while (dbus_connection_get_dispatch_status (connection
)
1707 != DBUS_DISPATCH_COMPLETE
)
1708 xd_read_message_1 (connection
, bus
);
1712 /* Callback called when something is ready to read or write. */
1714 xd_read_queued_messages (int fd
, void *data
)
1716 Lisp_Object busp
= xd_registered_buses
;
1717 Lisp_Object bus
= Qnil
;
1720 /* Find bus related to fd. */
1722 while (!NILP (busp
))
1724 key
= CAR_SAFE (CAR_SAFE (busp
));
1725 if ((SYMBOLP (key
) && XSYMBOL (key
) == data
)
1726 || (STRINGP (key
) && XSTRING (key
) == data
))
1728 busp
= CDR_SAFE (busp
);
1734 /* We ignore all Lisp errors during the call. */
1735 xd_in_read_queued_messages
= 1;
1736 internal_catch (Qdbus_error
, xd_read_message
, bus
);
1737 xd_in_read_queued_messages
= 0;
1742 syms_of_dbusbind (void)
1745 DEFSYM (Qdbus_init_bus
, "dbus-init-bus");
1746 defsubr (&Sdbus_init_bus
);
1748 DEFSYM (Qdbus_get_unique_name
, "dbus-get-unique-name");
1749 defsubr (&Sdbus_get_unique_name
);
1751 DEFSYM (Qdbus_message_internal
, "dbus-message-internal");
1752 defsubr (&Sdbus_message_internal
);
1754 DEFSYM (Qdbus_error
, "dbus-error");
1755 Fput (Qdbus_error
, Qerror_conditions
,
1756 list2 (Qdbus_error
, Qerror
));
1757 Fput (Qdbus_error
, Qerror_message
,
1758 build_pure_c_string ("D-Bus error"));
1760 DEFSYM (QCdbus_system_bus
, ":system");
1761 DEFSYM (QCdbus_session_bus
, ":session");
1762 DEFSYM (QCdbus_timeout
, ":timeout");
1763 DEFSYM (QCdbus_type_byte
, ":byte");
1764 DEFSYM (QCdbus_type_boolean
, ":boolean");
1765 DEFSYM (QCdbus_type_int16
, ":int16");
1766 DEFSYM (QCdbus_type_uint16
, ":uint16");
1767 DEFSYM (QCdbus_type_int32
, ":int32");
1768 DEFSYM (QCdbus_type_uint32
, ":uint32");
1769 DEFSYM (QCdbus_type_int64
, ":int64");
1770 DEFSYM (QCdbus_type_uint64
, ":uint64");
1771 DEFSYM (QCdbus_type_double
, ":double");
1772 DEFSYM (QCdbus_type_string
, ":string");
1773 DEFSYM (QCdbus_type_object_path
, ":object-path");
1774 DEFSYM (QCdbus_type_signature
, ":signature");
1775 #ifdef DBUS_TYPE_UNIX_FD
1776 DEFSYM (QCdbus_type_unix_fd
, ":unix-fd");
1778 DEFSYM (QCdbus_type_array
, ":array");
1779 DEFSYM (QCdbus_type_variant
, ":variant");
1780 DEFSYM (QCdbus_type_struct
, ":struct");
1781 DEFSYM (QCdbus_type_dict_entry
, ":dict-entry");
1782 DEFSYM (QCdbus_registered_serial
, ":serial");
1783 DEFSYM (QCdbus_registered_method
, ":method");
1784 DEFSYM (QCdbus_registered_signal
, ":signal");
1786 DEFVAR_LISP ("dbus-compiled-version",
1787 Vdbus_compiled_version
,
1788 doc
: /* The version of D-Bus Emacs is compiled against. */);
1789 #ifdef DBUS_VERSION_STRING
1790 Vdbus_compiled_version
= build_pure_c_string (DBUS_VERSION_STRING
);
1792 Vdbus_compiled_version
= Qnil
;
1795 DEFVAR_LISP ("dbus-runtime-version",
1796 Vdbus_runtime_version
,
1797 doc
: /* The version of D-Bus Emacs runs with. */);
1800 int major
, minor
, micro
;
1801 char s
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
1802 dbus_get_version (&major
, &minor
, µ
);
1803 Vdbus_runtime_version
1804 = make_formatted_string (s
, "%d.%d.%d", major
, minor
, micro
);
1806 Vdbus_runtime_version
= Qnil
;
1810 DEFVAR_LISP ("dbus-message-type-invalid",
1811 Vdbus_message_type_invalid
,
1812 doc
: /* This value is never a valid message type. */);
1813 Vdbus_message_type_invalid
= make_number (DBUS_MESSAGE_TYPE_INVALID
);
1815 DEFVAR_LISP ("dbus-message-type-method-call",
1816 Vdbus_message_type_method_call
,
1817 doc
: /* Message type of a method call message. */);
1818 Vdbus_message_type_method_call
= make_number (DBUS_MESSAGE_TYPE_METHOD_CALL
);
1820 DEFVAR_LISP ("dbus-message-type-method-return",
1821 Vdbus_message_type_method_return
,
1822 doc
: /* Message type of a method return message. */);
1823 Vdbus_message_type_method_return
1824 = make_number (DBUS_MESSAGE_TYPE_METHOD_RETURN
);
1826 DEFVAR_LISP ("dbus-message-type-error",
1827 Vdbus_message_type_error
,
1828 doc
: /* Message type of an error reply message. */);
1829 Vdbus_message_type_error
= make_number (DBUS_MESSAGE_TYPE_ERROR
);
1831 DEFVAR_LISP ("dbus-message-type-signal",
1832 Vdbus_message_type_signal
,
1833 doc
: /* Message type of a signal message. */);
1834 Vdbus_message_type_signal
= make_number (DBUS_MESSAGE_TYPE_SIGNAL
);
1836 DEFVAR_LISP ("dbus-registered-objects-table",
1837 Vdbus_registered_objects_table
,
1838 doc
: /* Hash table of registered functions for D-Bus.
1840 There are two different uses of the hash table: for accessing
1841 registered interfaces properties, targeted by signals or method calls,
1842 and for calling handlers in case of non-blocking method call returns.
1844 In the first case, the key in the hash table is the list (TYPE BUS
1845 INTERFACE MEMBER). TYPE is one of the Lisp symbols `:method',
1846 `:signal' or `:property'. BUS is either a Lisp symbol, `:system' or
1847 `:session', or a string denoting the bus address. INTERFACE is a
1848 string which denotes a D-Bus interface, and MEMBER, also a string, is
1849 either a method, a signal or a property INTERFACE is offering. All
1850 arguments but BUS must not be nil.
1852 The value in the hash table is a list of quadruple lists \((UNAME
1853 SERVICE PATH OBJECT [RULE]) ...). SERVICE is the service name as
1854 registered, UNAME is the corresponding unique name. In case of
1855 registered methods and properties, UNAME is nil. PATH is the object
1856 path of the sending object. All of them can be nil, which means a
1857 wildcard then. OBJECT is either the handler to be called when a D-Bus
1858 message, which matches the key criteria, arrives (TYPE `:method' and
1859 `:signal'), or a cons cell containing the value of the property (TYPE
1862 For entries of type `:signal', there is also a fifth element RULE,
1863 which keeps the match string the signal is registered with.
1865 In the second case, the key in the hash table is the list (:serial BUS
1866 SERIAL). BUS is either a Lisp symbol, `:system' or `:session', or a
1867 string denoting the bus address. SERIAL is the serial number of the
1868 non-blocking method call, a reply is expected. Both arguments must
1869 not be nil. The value in the hash table is HANDLER, the function to
1870 be called when the D-Bus reply message arrives. */);
1872 Lisp_Object args
[2];
1875 Vdbus_registered_objects_table
= Fmake_hash_table (2, args
);
1878 DEFVAR_LISP ("dbus-debug", Vdbus_debug
,
1879 doc
: /* If non-nil, debug messages of D-Bus bindings are raised. */);
1882 /* We can also set environment variable DBUS_VERBOSE=1 in order to
1883 see more traces. This requires libdbus-1 to be configured with
1884 --enable-verbose-mode. */
1889 /* Initialize internal objects. */
1890 xd_registered_buses
= Qnil
;
1891 staticpro (&xd_registered_buses
);
1893 Fprovide (intern_c_string ("dbusbind"), Qnil
);
1897 #endif /* HAVE_DBUS */