1 /* Elisp bindings for D-Bus.
2 Copyright (C) 2007-2015 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. */
44 /* Alist of D-Bus buses we are polling for messages.
45 The key is the symbol or string of the bus, and the value is the
46 connection address. */
47 static Lisp_Object xd_registered_buses
;
49 /* Whether we are reading a D-Bus event. */
50 static bool xd_in_read_queued_messages
= 0;
53 /* We use "xd_" and "XD_" as prefix for all internal symbols, because
54 we don't want to poison other namespaces with "dbus_". */
56 /* Raise a signal. If we are reading events, we cannot signal; we
57 throw to xd_read_queued_messages then. */
58 #define XD_SIGNAL1(arg) \
60 if (xd_in_read_queued_messages) \
61 Fthrow (Qdbus_error, Qnil); \
63 xsignal1 (Qdbus_error, arg); \
66 #define XD_SIGNAL2(arg1, arg2) \
68 if (xd_in_read_queued_messages) \
69 Fthrow (Qdbus_error, Qnil); \
71 xsignal2 (Qdbus_error, arg1, arg2); \
74 #define XD_SIGNAL3(arg1, arg2, arg3) \
76 if (xd_in_read_queued_messages) \
77 Fthrow (Qdbus_error, Qnil); \
79 xsignal3 (Qdbus_error, arg1, arg2, arg3); \
82 /* Raise a Lisp error from a D-Bus ERROR. */
83 #define XD_ERROR(error) \
85 /* Remove the trailing newline. */ \
86 char const *mess = error.message; \
87 char const *nl = strchr (mess, '\n'); \
88 Lisp_Object err = make_string (mess, nl ? nl - mess : strlen (mess)); \
89 dbus_error_free (&error); \
93 /* Macros for debugging. In order to enable them, build with
94 "env MYCPPFLAGS='-DDBUS_DEBUG -Wall' make". */
96 #define XD_DEBUG_MESSAGE(...) \
99 snprintf (s, sizeof s, __VA_ARGS__); \
100 if (!noninteractive) \
101 printf ("%s: %s\n", __func__, s); \
102 message ("%s: %s", __func__, s); \
104 #define XD_DEBUG_VALID_LISP_OBJECT_P(object) \
106 if (!valid_lisp_object_p (object)) \
108 XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__); \
109 XD_SIGNAL1 (build_string ("Assertion failure")); \
113 #else /* !DBUS_DEBUG */
114 # define XD_DEBUG_MESSAGE(...) \
116 if (!NILP (Vdbus_debug)) \
119 snprintf (s, sizeof s, __VA_ARGS__); \
120 message ("%s: %s", __func__, s); \
123 # define XD_DEBUG_VALID_LISP_OBJECT_P(object)
126 /* Check whether TYPE is a basic DBusType. */
127 #ifdef HAVE_DBUS_TYPE_IS_VALID
128 #define XD_BASIC_DBUS_TYPE(type) \
129 (dbus_type_is_valid (type) && dbus_type_is_basic (type))
131 #ifdef DBUS_TYPE_UNIX_FD
132 #define XD_BASIC_DBUS_TYPE(type) \
133 ((type == DBUS_TYPE_BYTE) \
134 || (type == DBUS_TYPE_BOOLEAN) \
135 || (type == DBUS_TYPE_INT16) \
136 || (type == DBUS_TYPE_UINT16) \
137 || (type == DBUS_TYPE_INT32) \
138 || (type == DBUS_TYPE_UINT32) \
139 || (type == DBUS_TYPE_INT64) \
140 || (type == DBUS_TYPE_UINT64) \
141 || (type == DBUS_TYPE_DOUBLE) \
142 || (type == DBUS_TYPE_STRING) \
143 || (type == DBUS_TYPE_OBJECT_PATH) \
144 || (type == DBUS_TYPE_SIGNATURE) \
145 || (type == DBUS_TYPE_UNIX_FD))
147 #define XD_BASIC_DBUS_TYPE(type) \
148 ((type == DBUS_TYPE_BYTE) \
149 || (type == DBUS_TYPE_BOOLEAN) \
150 || (type == DBUS_TYPE_INT16) \
151 || (type == DBUS_TYPE_UINT16) \
152 || (type == DBUS_TYPE_INT32) \
153 || (type == DBUS_TYPE_UINT32) \
154 || (type == DBUS_TYPE_INT64) \
155 || (type == DBUS_TYPE_UINT64) \
156 || (type == DBUS_TYPE_DOUBLE) \
157 || (type == DBUS_TYPE_STRING) \
158 || (type == DBUS_TYPE_OBJECT_PATH) \
159 || (type == DBUS_TYPE_SIGNATURE))
163 /* This was a macro. On Solaris 2.11 it was said to compile for
164 hours, when optimization is enabled. So we have transferred it into
166 /* Determine the DBusType of a given Lisp symbol. OBJECT must be one
167 of the predefined D-Bus type symbols. */
169 xd_symbol_to_dbus_type (Lisp_Object object
)
172 ((EQ (object
, QCdbus_type_byte
)) ? DBUS_TYPE_BYTE
173 : (EQ (object
, QCdbus_type_boolean
)) ? DBUS_TYPE_BOOLEAN
174 : (EQ (object
, QCdbus_type_int16
)) ? DBUS_TYPE_INT16
175 : (EQ (object
, QCdbus_type_uint16
)) ? DBUS_TYPE_UINT16
176 : (EQ (object
, QCdbus_type_int32
)) ? DBUS_TYPE_INT32
177 : (EQ (object
, QCdbus_type_uint32
)) ? DBUS_TYPE_UINT32
178 : (EQ (object
, QCdbus_type_int64
)) ? DBUS_TYPE_INT64
179 : (EQ (object
, QCdbus_type_uint64
)) ? DBUS_TYPE_UINT64
180 : (EQ (object
, QCdbus_type_double
)) ? DBUS_TYPE_DOUBLE
181 : (EQ (object
, QCdbus_type_string
)) ? DBUS_TYPE_STRING
182 : (EQ (object
, QCdbus_type_object_path
)) ? DBUS_TYPE_OBJECT_PATH
183 : (EQ (object
, QCdbus_type_signature
)) ? DBUS_TYPE_SIGNATURE
184 #ifdef DBUS_TYPE_UNIX_FD
185 : (EQ (object
, QCdbus_type_unix_fd
)) ? DBUS_TYPE_UNIX_FD
187 : (EQ (object
, QCdbus_type_array
)) ? DBUS_TYPE_ARRAY
188 : (EQ (object
, QCdbus_type_variant
)) ? DBUS_TYPE_VARIANT
189 : (EQ (object
, QCdbus_type_struct
)) ? DBUS_TYPE_STRUCT
190 : (EQ (object
, QCdbus_type_dict_entry
)) ? DBUS_TYPE_DICT_ENTRY
191 : DBUS_TYPE_INVALID
);
194 /* Check whether a Lisp symbol is a predefined D-Bus type symbol. */
195 #define XD_DBUS_TYPE_P(object) \
196 (SYMBOLP (object) && ((xd_symbol_to_dbus_type (object) != DBUS_TYPE_INVALID)))
198 /* Determine the DBusType of a given Lisp OBJECT. It is used to
199 convert Lisp objects, being arguments of `dbus-call-method' or
200 `dbus-send-signal', into corresponding C values appended as
201 arguments to a D-Bus message. */
202 #define XD_OBJECT_TO_DBUS_TYPE(object) \
203 ((EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN \
204 : (NATNUMP (object)) ? DBUS_TYPE_UINT32 \
205 : (INTEGERP (object)) ? DBUS_TYPE_INT32 \
206 : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \
207 : (STRINGP (object)) ? DBUS_TYPE_STRING \
208 : (XD_DBUS_TYPE_P (object)) ? xd_symbol_to_dbus_type (object) \
210 ? ((XD_DBUS_TYPE_P (CAR_SAFE (object))) \
211 ? ((XD_BASIC_DBUS_TYPE (xd_symbol_to_dbus_type (CAR_SAFE (object)))) \
213 : xd_symbol_to_dbus_type (CAR_SAFE (object))) \
217 /* Return a list pointer which does not have a Lisp symbol as car. */
218 #define XD_NEXT_VALUE(object) \
219 ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object)
221 /* Transform the message type to its string representation for debug
223 #define XD_MESSAGE_TYPE_TO_STRING(mtype) \
224 ((mtype == DBUS_MESSAGE_TYPE_INVALID) \
225 ? "DBUS_MESSAGE_TYPE_INVALID" \
226 : (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) \
227 ? "DBUS_MESSAGE_TYPE_METHOD_CALL" \
228 : (mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) \
229 ? "DBUS_MESSAGE_TYPE_METHOD_RETURN" \
230 : (mtype == DBUS_MESSAGE_TYPE_ERROR) \
231 ? "DBUS_MESSAGE_TYPE_ERROR" \
232 : "DBUS_MESSAGE_TYPE_SIGNAL")
234 /* Transform the object to its string representation for debug
236 #define XD_OBJECT_TO_STRING(object) \
237 SDATA (format2 ("%s", object, Qnil))
239 #define XD_DBUS_VALIDATE_BUS_ADDRESS(bus) \
241 char const *session_bus_address = getenv ("DBUS_SESSION_BUS_ADDRESS"); \
244 DBusAddressEntry **entries; \
247 dbus_error_init (&derror); \
248 if (!dbus_parse_address (SSDATA (bus), &entries, &len, &derror)) \
251 dbus_error_free (&derror); \
252 dbus_address_entries_free (entries); \
253 /* Canonicalize session bus address. */ \
254 if ((session_bus_address != NULL) \
255 && (!NILP (Fstring_equal \
256 (bus, build_string (session_bus_address))))) \
257 bus = QCdbus_session_bus; \
262 CHECK_SYMBOL (bus); \
263 if (!(EQ (bus, QCdbus_system_bus) || EQ (bus, QCdbus_session_bus))) \
264 XD_SIGNAL2 (build_string ("Wrong bus name"), bus); \
265 /* We do not want to have an autolaunch for the session bus. */ \
266 if (EQ (bus, QCdbus_session_bus) && session_bus_address == NULL) \
267 XD_SIGNAL2 (build_string ("No connection to bus"), bus); \
271 #if (HAVE_DBUS_VALIDATE_BUS_NAME || HAVE_DBUS_VALIDATE_PATH \
272 || HAVE_DBUS_VALIDATE_INTERFACE || HAVE_DBUS_VALIDATE_MEMBER)
273 #define XD_DBUS_VALIDATE_OBJECT(object, func) \
275 if (!NILP (object)) \
278 CHECK_STRING (object); \
279 dbus_error_init (&derror); \
280 if (!func (SSDATA (object), &derror)) \
283 dbus_error_free (&derror); \
288 #if HAVE_DBUS_VALIDATE_BUS_NAME
289 #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \
290 XD_DBUS_VALIDATE_OBJECT(bus_name, dbus_validate_bus_name);
292 #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \
293 if (!NILP (bus_name)) CHECK_STRING (bus_name);
296 #if HAVE_DBUS_VALIDATE_PATH
297 #define XD_DBUS_VALIDATE_PATH(path) \
298 XD_DBUS_VALIDATE_OBJECT(path, dbus_validate_path);
300 #define XD_DBUS_VALIDATE_PATH(path) \
301 if (!NILP (path)) CHECK_STRING (path);
304 #if HAVE_DBUS_VALIDATE_INTERFACE
305 #define XD_DBUS_VALIDATE_INTERFACE(interface) \
306 XD_DBUS_VALIDATE_OBJECT(interface, dbus_validate_interface);
308 #define XD_DBUS_VALIDATE_INTERFACE(interface) \
309 if (!NILP (interface)) CHECK_STRING (interface);
312 #if HAVE_DBUS_VALIDATE_MEMBER
313 #define XD_DBUS_VALIDATE_MEMBER(member) \
314 XD_DBUS_VALIDATE_OBJECT(member, dbus_validate_member);
316 #define XD_DBUS_VALIDATE_MEMBER(member) \
317 if (!NILP (member)) CHECK_STRING (member);
320 /* Append to SIGNATURE a copy of X, making sure SIGNATURE does
321 not become too long. */
323 xd_signature_cat (char *signature
, char const *x
)
325 ptrdiff_t siglen
= strlen (signature
);
326 ptrdiff_t xlen
= strlen (x
);
327 if (DBUS_MAXIMUM_SIGNATURE_LENGTH
- xlen
<= siglen
)
329 strcpy (signature
+ siglen
, x
);
332 /* Compute SIGNATURE of OBJECT. It must have a form that it can be
333 used in dbus_message_iter_open_container. DTYPE is the DBusType
334 the object is related to. It is passed as argument, because it
335 cannot be detected in basic type objects, when they are preceded by
336 a type symbol. PARENT_TYPE is the DBusType of a container this
337 signature is embedded, or DBUS_TYPE_INVALID. It is needed for the
338 check that DBUS_TYPE_DICT_ENTRY occurs only as array element. */
340 xd_signature (char *signature
, int dtype
, int parent_type
, Lisp_Object object
)
346 char x
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
353 case DBUS_TYPE_UINT16
:
354 CHECK_NATNUM (object
);
355 sprintf (signature
, "%c", dtype
);
358 case DBUS_TYPE_BOOLEAN
:
359 if (!EQ (object
, Qt
) && !EQ (object
, Qnil
))
360 wrong_type_argument (intern ("booleanp"), object
);
361 sprintf (signature
, "%c", dtype
);
364 case DBUS_TYPE_INT16
:
365 CHECK_NUMBER (object
);
366 sprintf (signature
, "%c", dtype
);
369 case DBUS_TYPE_UINT32
:
370 case DBUS_TYPE_UINT64
:
371 #ifdef DBUS_TYPE_UNIX_FD
372 case DBUS_TYPE_UNIX_FD
:
374 case DBUS_TYPE_INT32
:
375 case DBUS_TYPE_INT64
:
376 case DBUS_TYPE_DOUBLE
:
377 CHECK_NUMBER_OR_FLOAT (object
);
378 sprintf (signature
, "%c", dtype
);
381 case DBUS_TYPE_STRING
:
382 case DBUS_TYPE_OBJECT_PATH
:
383 case DBUS_TYPE_SIGNATURE
:
384 CHECK_STRING (object
);
385 sprintf (signature
, "%c", dtype
);
388 case DBUS_TYPE_ARRAY
:
389 /* Check that all list elements have the same D-Bus type. For
390 complex element types, we just check the container type, not
391 the whole element's signature. */
394 /* Type symbol is optional. */
395 if (EQ (QCdbus_type_array
, CAR_SAFE (elt
)))
396 elt
= XD_NEXT_VALUE (elt
);
398 /* If the array is empty, DBUS_TYPE_STRING is the default
402 subtype
= DBUS_TYPE_STRING
;
403 subsig
= DBUS_TYPE_STRING_AS_STRING
;
407 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
408 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
412 /* If the element type is DBUS_TYPE_SIGNATURE, and this is the
413 only element, the value of this element is used as the
414 array's element signature. */
415 if ((subtype
== DBUS_TYPE_SIGNATURE
)
416 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt
)))
417 && NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
418 subsig
= SSDATA (CAR_SAFE (XD_NEXT_VALUE (elt
)));
422 if (subtype
!= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
)))
423 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (elt
));
424 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
427 subsiglen
= snprintf (signature
, DBUS_MAXIMUM_SIGNATURE_LENGTH
,
428 "%c%s", dtype
, subsig
);
429 if (! (0 <= subsiglen
&& subsiglen
< DBUS_MAXIMUM_SIGNATURE_LENGTH
))
433 case DBUS_TYPE_VARIANT
:
434 /* Check that there is exactly one list element. */
437 elt
= XD_NEXT_VALUE (elt
);
438 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
439 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
441 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
442 wrong_type_argument (intern ("D-Bus"),
443 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt
))));
445 sprintf (signature
, "%c", dtype
);
448 case DBUS_TYPE_STRUCT
:
449 /* A struct list might contain any number of elements with
450 different types. No further check needed. */
453 elt
= XD_NEXT_VALUE (elt
);
455 /* Compose the signature from the elements. It is enclosed by
457 sprintf (signature
, "%c", DBUS_STRUCT_BEGIN_CHAR
);
460 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
461 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
462 xd_signature_cat (signature
, x
);
463 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
465 xd_signature_cat (signature
, DBUS_STRUCT_END_CHAR_AS_STRING
);
468 case DBUS_TYPE_DICT_ENTRY
:
469 /* Check that there are exactly two list elements, and the first
470 one is of basic type. The dictionary entry itself must be an
471 element of an array. */
474 /* Check the parent object type. */
475 if (parent_type
!= DBUS_TYPE_ARRAY
)
476 wrong_type_argument (intern ("D-Bus"), object
);
478 /* Compose the signature from the elements. It is enclosed by
480 sprintf (signature
, "%c", DBUS_DICT_ENTRY_BEGIN_CHAR
);
483 elt
= XD_NEXT_VALUE (elt
);
484 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
485 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
486 xd_signature_cat (signature
, x
);
488 if (!XD_BASIC_DBUS_TYPE (subtype
))
489 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt
)));
491 /* Second element. */
492 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
493 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
494 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
495 xd_signature_cat (signature
, x
);
497 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
498 wrong_type_argument (intern ("D-Bus"),
499 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt
))));
501 /* Closing signature. */
502 xd_signature_cat (signature
, DBUS_DICT_ENTRY_END_CHAR_AS_STRING
);
506 wrong_type_argument (intern ("D-Bus"), object
);
509 XD_DEBUG_MESSAGE ("%s", signature
);
512 /* Convert X to a signed integer with bounds LO and HI. */
514 xd_extract_signed (Lisp_Object x
, intmax_t lo
, intmax_t hi
)
516 CHECK_NUMBER_OR_FLOAT (x
);
519 if (lo
<= XINT (x
) && XINT (x
) <= hi
)
524 double d
= XFLOAT_DATA (x
);
525 if (lo
<= d
&& d
<= hi
)
532 if (xd_in_read_queued_messages
)
533 Fthrow (Qdbus_error
, Qnil
);
535 args_out_of_range_3 (x
,
536 make_fixnum_or_float (lo
),
537 make_fixnum_or_float (hi
));
540 /* Convert X to an unsigned integer with bounds 0 and HI. */
542 xd_extract_unsigned (Lisp_Object x
, uintmax_t hi
)
544 CHECK_NUMBER_OR_FLOAT (x
);
547 if (0 <= XINT (x
) && XINT (x
) <= hi
)
552 double d
= XFLOAT_DATA (x
);
553 if (0 <= d
&& d
<= hi
)
560 if (xd_in_read_queued_messages
)
561 Fthrow (Qdbus_error
, Qnil
);
563 args_out_of_range_3 (x
, make_number (0), make_fixnum_or_float (hi
));
566 /* Append C value, extracted from Lisp OBJECT, to iteration ITER.
567 DTYPE must be a valid DBusType. It is used to convert Lisp
568 objects, being arguments of `dbus-call-method' or
569 `dbus-send-signal', into corresponding C values appended as
570 arguments to a D-Bus message. */
572 xd_append_arg (int dtype
, Lisp_Object object
, DBusMessageIter
*iter
)
574 char signature
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
575 DBusMessageIter subiter
;
577 if (XD_BASIC_DBUS_TYPE (dtype
))
581 CHECK_NATNUM (object
);
583 unsigned char val
= XFASTINT (object
) & 0xFF;
584 XD_DEBUG_MESSAGE ("%c %u", dtype
, val
);
585 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
586 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
590 case DBUS_TYPE_BOOLEAN
:
592 dbus_bool_t val
= (NILP (object
)) ? FALSE
: TRUE
;
593 XD_DEBUG_MESSAGE ("%c %s", dtype
, (val
== FALSE
) ? "false" : "true");
594 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
595 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
599 case DBUS_TYPE_INT16
:
602 xd_extract_signed (object
,
603 TYPE_MINIMUM (dbus_int16_t
),
604 TYPE_MAXIMUM (dbus_int16_t
));
606 XD_DEBUG_MESSAGE ("%c %d", dtype
, pval
);
607 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
608 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
612 case DBUS_TYPE_UINT16
:
615 xd_extract_unsigned (object
,
616 TYPE_MAXIMUM (dbus_uint16_t
));
617 unsigned int pval
= val
;
618 XD_DEBUG_MESSAGE ("%c %u", dtype
, pval
);
619 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
620 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
624 case DBUS_TYPE_INT32
:
627 xd_extract_signed (object
,
628 TYPE_MINIMUM (dbus_int32_t
),
629 TYPE_MAXIMUM (dbus_int32_t
));
631 XD_DEBUG_MESSAGE ("%c %d", dtype
, pval
);
632 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
633 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
637 case DBUS_TYPE_UINT32
:
638 #ifdef DBUS_TYPE_UNIX_FD
639 case DBUS_TYPE_UNIX_FD
:
643 xd_extract_unsigned (object
,
644 TYPE_MAXIMUM (dbus_uint32_t
));
645 unsigned int pval
= val
;
646 XD_DEBUG_MESSAGE ("%c %u", dtype
, pval
);
647 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
648 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
652 case DBUS_TYPE_INT64
:
655 xd_extract_signed (object
,
656 TYPE_MINIMUM (dbus_int64_t
),
657 TYPE_MAXIMUM (dbus_int64_t
));
658 printmax_t pval
= val
;
659 XD_DEBUG_MESSAGE ("%c %"pMd
, dtype
, pval
);
660 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
661 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
665 case DBUS_TYPE_UINT64
:
668 xd_extract_unsigned (object
,
669 TYPE_MAXIMUM (dbus_uint64_t
));
670 uprintmax_t pval
= val
;
671 XD_DEBUG_MESSAGE ("%c %"pMu
, dtype
, pval
);
672 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
673 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
677 case DBUS_TYPE_DOUBLE
:
679 double val
= extract_float (object
);
680 XD_DEBUG_MESSAGE ("%c %f", dtype
, val
);
681 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
682 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
686 case DBUS_TYPE_STRING
:
687 case DBUS_TYPE_OBJECT_PATH
:
688 case DBUS_TYPE_SIGNATURE
:
689 CHECK_STRING (object
);
691 /* We need to send a valid UTF-8 string. We could encode `object'
692 but by not encoding it, we guarantee it's valid utf-8, even if
693 it contains eight-bit-bytes. Of course, you can still send
694 manually-crafted junk by passing a unibyte string. */
695 char *val
= SSDATA (object
);
696 XD_DEBUG_MESSAGE ("%c %s", dtype
, val
);
697 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
698 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
703 else /* Compound types. */
706 /* All compound types except array have a type symbol. For
707 array, it is optional. Skip it. */
708 if (!XD_BASIC_DBUS_TYPE (XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
))))
709 object
= XD_NEXT_VALUE (object
);
711 /* Open new subiteration. */
714 case DBUS_TYPE_ARRAY
:
715 /* An array has only elements of the same type. So it is
716 sufficient to check the first element's signature
720 /* If the array is empty, DBUS_TYPE_STRING is the default
722 strcpy (signature
, DBUS_TYPE_STRING_AS_STRING
);
725 /* If the element type is DBUS_TYPE_SIGNATURE, and this is
726 the only element, the value of this element is used as
727 the array's element signature. */
728 if ((XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
))
729 == DBUS_TYPE_SIGNATURE
)
730 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object
)))
731 && NILP (CDR_SAFE (XD_NEXT_VALUE (object
))))
733 lispstpcpy (signature
, CAR_SAFE (XD_NEXT_VALUE (object
)));
734 object
= CDR_SAFE (XD_NEXT_VALUE (object
));
738 xd_signature (signature
,
739 XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
)),
740 dtype
, CAR_SAFE (XD_NEXT_VALUE (object
)));
742 XD_DEBUG_MESSAGE ("%c %s %s", dtype
, signature
,
743 XD_OBJECT_TO_STRING (object
));
744 if (!dbus_message_iter_open_container (iter
, dtype
,
745 signature
, &subiter
))
746 XD_SIGNAL3 (build_string ("Cannot open container"),
747 make_number (dtype
), build_string (signature
));
750 case DBUS_TYPE_VARIANT
:
751 /* A variant has just one element. */
752 xd_signature (signature
, XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
)),
753 dtype
, CAR_SAFE (XD_NEXT_VALUE (object
)));
755 XD_DEBUG_MESSAGE ("%c %s %s", dtype
, signature
,
756 XD_OBJECT_TO_STRING (object
));
757 if (!dbus_message_iter_open_container (iter
, dtype
,
758 signature
, &subiter
))
759 XD_SIGNAL3 (build_string ("Cannot open container"),
760 make_number (dtype
), build_string (signature
));
763 case DBUS_TYPE_STRUCT
:
764 case DBUS_TYPE_DICT_ENTRY
:
765 /* These containers do not require a signature. */
766 XD_DEBUG_MESSAGE ("%c %s", dtype
, XD_OBJECT_TO_STRING (object
));
767 if (!dbus_message_iter_open_container (iter
, dtype
, NULL
, &subiter
))
768 XD_SIGNAL2 (build_string ("Cannot open container"),
769 make_number (dtype
));
773 /* Loop over list elements. */
774 while (!NILP (object
))
776 dtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
));
777 object
= XD_NEXT_VALUE (object
);
779 xd_append_arg (dtype
, CAR_SAFE (object
), &subiter
);
781 object
= CDR_SAFE (object
);
784 /* Close the subiteration. */
785 if (!dbus_message_iter_close_container (iter
, &subiter
))
786 XD_SIGNAL2 (build_string ("Cannot close container"),
787 make_number (dtype
));
791 /* Retrieve C value from a DBusMessageIter structure ITER, and return
792 a converted Lisp object. The type DTYPE of the argument of the
793 D-Bus message must be a valid DBusType. Compound D-Bus types
794 result always in a Lisp list. */
796 xd_retrieve_arg (int dtype
, DBusMessageIter
*iter
)
804 dbus_message_iter_get_basic (iter
, &val
);
806 XD_DEBUG_MESSAGE ("%c %u", dtype
, val
);
807 return make_number (val
);
810 case DBUS_TYPE_BOOLEAN
:
813 dbus_message_iter_get_basic (iter
, &val
);
814 XD_DEBUG_MESSAGE ("%c %s", dtype
, (val
== FALSE
) ? "false" : "true");
815 return (val
== FALSE
) ? Qnil
: Qt
;
818 case DBUS_TYPE_INT16
:
822 dbus_message_iter_get_basic (iter
, &val
);
824 XD_DEBUG_MESSAGE ("%c %d", dtype
, pval
);
825 return make_number (val
);
828 case DBUS_TYPE_UINT16
:
832 dbus_message_iter_get_basic (iter
, &val
);
834 XD_DEBUG_MESSAGE ("%c %d", dtype
, pval
);
835 return make_number (val
);
838 case DBUS_TYPE_INT32
:
842 dbus_message_iter_get_basic (iter
, &val
);
844 XD_DEBUG_MESSAGE ("%c %d", dtype
, pval
);
845 return make_fixnum_or_float (val
);
848 case DBUS_TYPE_UINT32
:
849 #ifdef DBUS_TYPE_UNIX_FD
850 case DBUS_TYPE_UNIX_FD
:
855 dbus_message_iter_get_basic (iter
, &val
);
857 XD_DEBUG_MESSAGE ("%c %u", dtype
, pval
);
858 return make_fixnum_or_float (val
);
861 case DBUS_TYPE_INT64
:
865 dbus_message_iter_get_basic (iter
, &val
);
867 XD_DEBUG_MESSAGE ("%c %"pMd
, dtype
, pval
);
868 return make_fixnum_or_float (val
);
871 case DBUS_TYPE_UINT64
:
875 dbus_message_iter_get_basic (iter
, &val
);
877 XD_DEBUG_MESSAGE ("%c %"pMd
, dtype
, pval
);
878 return make_fixnum_or_float (val
);
881 case DBUS_TYPE_DOUBLE
:
884 dbus_message_iter_get_basic (iter
, &val
);
885 XD_DEBUG_MESSAGE ("%c %f", dtype
, val
);
886 return make_float (val
);
889 case DBUS_TYPE_STRING
:
890 case DBUS_TYPE_OBJECT_PATH
:
891 case DBUS_TYPE_SIGNATURE
:
894 dbus_message_iter_get_basic (iter
, &val
);
895 XD_DEBUG_MESSAGE ("%c %s", dtype
, val
);
896 return build_string (val
);
899 case DBUS_TYPE_ARRAY
:
900 case DBUS_TYPE_VARIANT
:
901 case DBUS_TYPE_STRUCT
:
902 case DBUS_TYPE_DICT_ENTRY
:
906 DBusMessageIter subiter
;
910 dbus_message_iter_recurse (iter
, &subiter
);
911 while ((subtype
= dbus_message_iter_get_arg_type (&subiter
))
912 != DBUS_TYPE_INVALID
)
914 result
= Fcons (xd_retrieve_arg (subtype
, &subiter
), result
);
915 dbus_message_iter_next (&subiter
);
917 XD_DEBUG_MESSAGE ("%c %s", dtype
, XD_OBJECT_TO_STRING (result
));
918 RETURN_UNGCPRO (Fnreverse (result
));
922 XD_DEBUG_MESSAGE ("DBusType '%c' not supported", dtype
);
927 /* Return the number of references of the shared CONNECTION. */
929 xd_get_connection_references (DBusConnection
*connection
)
933 /* We cannot access the DBusConnection structure, it is not public.
934 But we know, that the reference counter is the first field in
936 refcount
= (void *) &connection
;
937 refcount
= (void *) *refcount
;
941 /* Convert a Lisp D-Bus object to a pointer. */
942 static DBusConnection
*
943 xd_lisp_dbus_to_dbus (Lisp_Object bus
)
945 return (DBusConnection
*) (intptr_t) XFASTINT (bus
);
948 /* Return D-Bus connection address. BUS is either a Lisp symbol,
949 :system or :session, or a string denoting the bus address. */
950 static DBusConnection
*
951 xd_get_connection_address (Lisp_Object bus
)
953 DBusConnection
*connection
;
956 val
= CDR_SAFE (Fassoc (bus
, xd_registered_buses
));
958 XD_SIGNAL2 (build_string ("No connection to bus"), bus
);
960 connection
= xd_lisp_dbus_to_dbus (val
);
962 if (!dbus_connection_get_is_connected (connection
))
963 XD_SIGNAL2 (build_string ("No connection to bus"), bus
);
968 /* Return the file descriptor for WATCH, -1 if not found. */
970 xd_find_watch_fd (DBusWatch
*watch
)
972 #if HAVE_DBUS_WATCH_GET_UNIX_FD
973 /* TODO: Reverse these on w32, which prefers the opposite. */
974 int fd
= dbus_watch_get_unix_fd (watch
);
976 fd
= dbus_watch_get_socket (watch
);
978 int fd
= dbus_watch_get_fd (watch
);
984 static void xd_read_queued_messages (int fd
, void *data
);
986 /* Start monitoring WATCH for possible I/O. */
988 xd_add_watch (DBusWatch
*watch
, void *data
)
990 unsigned int flags
= dbus_watch_get_flags (watch
);
991 int fd
= xd_find_watch_fd (watch
);
993 XD_DEBUG_MESSAGE ("fd %d, write %d, enabled %d",
994 fd
, flags
& DBUS_WATCH_WRITABLE
,
995 dbus_watch_get_enabled (watch
));
1000 if (dbus_watch_get_enabled (watch
))
1002 if (flags
& DBUS_WATCH_WRITABLE
)
1003 add_write_fd (fd
, xd_read_queued_messages
, data
);
1004 if (flags
& DBUS_WATCH_READABLE
)
1005 add_read_fd (fd
, xd_read_queued_messages
, data
);
1010 /* Stop monitoring WATCH for possible I/O.
1011 DATA is the used bus, either a string or QCdbus_system_bus or
1012 QCdbus_session_bus. */
1014 xd_remove_watch (DBusWatch
*watch
, void *data
)
1016 unsigned int flags
= dbus_watch_get_flags (watch
);
1017 int fd
= xd_find_watch_fd (watch
);
1019 XD_DEBUG_MESSAGE ("fd %d", fd
);
1024 /* Unset session environment. */
1026 /* This is buggy, since unsetenv is not thread-safe. */
1027 if (XSYMBOL (QCdbus_session_bus
) == data
)
1029 XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
1030 unsetenv ("DBUS_SESSION_BUS_ADDRESS");
1034 if (flags
& DBUS_WATCH_WRITABLE
)
1035 delete_write_fd (fd
);
1036 if (flags
& DBUS_WATCH_READABLE
)
1037 delete_read_fd (fd
);
1040 /* Toggle monitoring WATCH for possible I/O. */
1042 xd_toggle_watch (DBusWatch
*watch
, void *data
)
1044 if (dbus_watch_get_enabled (watch
))
1045 xd_add_watch (watch
, data
);
1047 xd_remove_watch (watch
, data
);
1050 /* Close connection to D-Bus BUS. */
1052 xd_close_bus (Lisp_Object bus
)
1054 DBusConnection
*connection
;
1058 /* Check whether we are connected. */
1059 val
= Fassoc (bus
, xd_registered_buses
);
1063 busobj
= CDR_SAFE (val
);
1064 if (NILP (busobj
)) {
1065 xd_registered_buses
= Fdelete (val
, xd_registered_buses
);
1069 /* Retrieve bus address. */
1070 connection
= xd_lisp_dbus_to_dbus (busobj
);
1072 if (xd_get_connection_references (connection
) == 1)
1074 /* Close connection, if there isn't another shared application. */
1075 XD_DEBUG_MESSAGE ("Close connection to bus %s",
1076 XD_OBJECT_TO_STRING (bus
));
1077 dbus_connection_close (connection
);
1079 xd_registered_buses
= Fdelete (val
, xd_registered_buses
);
1083 /* Decrement reference count. */
1084 dbus_connection_unref (connection
);
1090 DEFUN ("dbus--init-bus", Fdbus__init_bus
, Sdbus__init_bus
, 1, 2, 0,
1091 doc
: /* Establish the connection to D-Bus BUS.
1093 This function is dbus internal. You almost certainly want to use
1096 BUS can be either the symbol `:system' or the symbol `:session', or it
1097 can be a string denoting the address of the corresponding bus. For
1098 the system and session buses, this function is called when loading
1099 `dbus.el', there is no need to call it again.
1101 The function returns a number, which counts the connections this Emacs
1102 session has established to the BUS under the same unique name (see
1103 `dbus-get-unique-name'). It depends on the libraries Emacs is linked
1104 with, and on the environment Emacs is running. For example, if Emacs
1105 is linked with the gtk toolkit, and it runs in a GTK-aware environment
1106 like Gnome, another connection might already be established.
1108 When PRIVATE is non-nil, a new connection is established instead of
1109 reusing an existing one. It results in a new unique name at the bus.
1110 This can be used, if it is necessary to distinguish from another
1111 connection used in the same Emacs process, like the one established by
1112 GTK+. It should be used with care for at least the `:system' and
1113 `:session' buses, because other Emacs Lisp packages might already use
1114 this connection to those buses. */)
1115 (Lisp_Object bus
, Lisp_Object
private)
1117 DBusConnection
*connection
;
1122 /* Check parameter. */
1123 XD_DBUS_VALIDATE_BUS_ADDRESS (bus
);
1125 /* Close bus if it is already open. */
1128 /* Check, whether we are still connected. */
1129 val
= Fassoc (bus
, xd_registered_buses
);
1132 connection
= xd_get_connection_address (bus
);
1133 dbus_connection_ref (connection
);
1139 dbus_error_init (&derror
);
1141 /* Open the connection. */
1144 connection
= dbus_connection_open (SSDATA (bus
), &derror
);
1146 connection
= dbus_connection_open_private (SSDATA (bus
), &derror
);
1150 connection
= dbus_bus_get (EQ (bus
, QCdbus_system_bus
)
1151 ? DBUS_BUS_SYSTEM
: DBUS_BUS_SESSION
,
1154 connection
= dbus_bus_get_private (EQ (bus
, QCdbus_system_bus
)
1155 ? DBUS_BUS_SYSTEM
: DBUS_BUS_SESSION
,
1158 if (dbus_error_is_set (&derror
))
1161 if (connection
== NULL
)
1162 XD_SIGNAL2 (build_string ("No connection to bus"), bus
);
1164 /* If it is not the system or session bus, we must register
1165 ourselves. Otherwise, we have called dbus_bus_get, which has
1166 configured us to exit if the connection closes - we undo this
1169 dbus_bus_register (connection
, &derror
);
1171 dbus_connection_set_exit_on_disconnect (connection
, FALSE
);
1173 if (dbus_error_is_set (&derror
))
1176 /* Add the watch functions. We pass also the bus as data, in
1177 order to distinguish between the buses in xd_remove_watch. */
1178 if (!dbus_connection_set_watch_functions (connection
,
1183 ? (void *) XSYMBOL (bus
)
1184 : (void *) XSTRING (bus
),
1186 XD_SIGNAL1 (build_string ("Cannot add watch functions"));
1188 /* Add bus to list of registered buses. */
1189 XSETFASTINT (val
, (intptr_t) connection
);
1190 xd_registered_buses
= Fcons (Fcons (bus
, val
), xd_registered_buses
);
1193 dbus_error_free (&derror
);
1196 /* Return reference counter. */
1197 refcount
= xd_get_connection_references (connection
);
1198 XD_DEBUG_MESSAGE ("Bus %s, Reference counter %"pD
"d",
1199 XD_OBJECT_TO_STRING (bus
), refcount
);
1200 return make_number (refcount
);
1203 DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name
, Sdbus_get_unique_name
,
1205 doc
: /* Return the unique name of Emacs registered at D-Bus BUS. */)
1208 DBusConnection
*connection
;
1211 /* Check parameter. */
1212 XD_DBUS_VALIDATE_BUS_ADDRESS (bus
);
1214 /* Retrieve bus address. */
1215 connection
= xd_get_connection_address (bus
);
1217 /* Request the name. */
1218 name
= dbus_bus_get_unique_name (connection
);
1220 XD_SIGNAL1 (build_string ("No unique name available"));
1223 return build_string (name
);
1226 DEFUN ("dbus-message-internal", Fdbus_message_internal
, Sdbus_message_internal
,
1228 doc
: /* Send a D-Bus message.
1229 This is an internal function, it shall not be used outside dbus.el.
1231 The following usages are expected:
1233 `dbus-call-method', `dbus-call-method-asynchronously':
1234 \(dbus-message-internal
1235 dbus-message-type-method-call BUS SERVICE PATH INTERFACE METHOD HANDLER
1236 &optional :timeout TIMEOUT &rest ARGS)
1239 \(dbus-message-internal
1240 dbus-message-type-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS)
1242 `dbus-method-return-internal':
1243 \(dbus-message-internal
1244 dbus-message-type-method-return BUS SERVICE SERIAL &rest ARGS)
1246 `dbus-method-error-internal':
1247 \(dbus-message-internal
1248 dbus-message-type-error BUS SERVICE SERIAL &rest ARGS)
1250 usage: (dbus-message-internal &rest REST) */)
1251 (ptrdiff_t nargs
, Lisp_Object
*args
)
1253 Lisp_Object message_type
, bus
, service
, handler
;
1254 Lisp_Object path
= Qnil
;
1255 Lisp_Object interface
= Qnil
;
1256 Lisp_Object member
= Qnil
;
1258 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
1259 DBusConnection
*connection
;
1260 DBusMessage
*dmessage
;
1261 DBusMessageIter iter
;
1264 dbus_uint32_t serial
= 0;
1265 unsigned int ui_serial
;
1268 char signature
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
1270 /* Initialize parameters. */
1271 message_type
= args
[0];
1276 CHECK_NATNUM (message_type
);
1277 if (! (DBUS_MESSAGE_TYPE_INVALID
< XFASTINT (message_type
)
1278 && XFASTINT (message_type
) < DBUS_NUM_MESSAGE_TYPES
))
1279 XD_SIGNAL2 (build_string ("Invalid message type"), message_type
);
1280 mtype
= XFASTINT (message_type
);
1282 if ((mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1283 || (mtype
== DBUS_MESSAGE_TYPE_SIGNAL
))
1286 interface
= args
[4];
1288 if (mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1290 count
= (mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
) ? 7 : 6;
1292 else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1294 serial
= xd_extract_unsigned (args
[3], TYPE_MAXIMUM (dbus_uint32_t
));
1298 /* Check parameters. */
1299 XD_DBUS_VALIDATE_BUS_ADDRESS (bus
);
1300 XD_DBUS_VALIDATE_BUS_NAME (service
);
1302 xsignal2 (Qwrong_number_of_arguments
,
1303 Qdbus_message_internal
,
1304 make_number (nargs
));
1306 if ((mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1307 || (mtype
== DBUS_MESSAGE_TYPE_SIGNAL
))
1309 XD_DBUS_VALIDATE_PATH (path
);
1310 XD_DBUS_VALIDATE_INTERFACE (interface
);
1311 XD_DBUS_VALIDATE_MEMBER (member
);
1312 if (!NILP (handler
) && (!FUNCTIONP (handler
)))
1313 wrong_type_argument (Qinvalid_function
, handler
);
1316 /* Protect Lisp variables. */
1317 GCPRO6 (bus
, service
, path
, interface
, member
, handler
);
1319 /* Trace parameters. */
1322 case DBUS_MESSAGE_TYPE_METHOD_CALL
:
1323 XD_DEBUG_MESSAGE ("%s %s %s %s %s %s %s",
1324 XD_MESSAGE_TYPE_TO_STRING (mtype
),
1325 XD_OBJECT_TO_STRING (bus
),
1326 XD_OBJECT_TO_STRING (service
),
1327 XD_OBJECT_TO_STRING (path
),
1328 XD_OBJECT_TO_STRING (interface
),
1329 XD_OBJECT_TO_STRING (member
),
1330 XD_OBJECT_TO_STRING (handler
));
1332 case DBUS_MESSAGE_TYPE_SIGNAL
:
1333 XD_DEBUG_MESSAGE ("%s %s %s %s %s %s",
1334 XD_MESSAGE_TYPE_TO_STRING (mtype
),
1335 XD_OBJECT_TO_STRING (bus
),
1336 XD_OBJECT_TO_STRING (service
),
1337 XD_OBJECT_TO_STRING (path
),
1338 XD_OBJECT_TO_STRING (interface
),
1339 XD_OBJECT_TO_STRING (member
));
1341 default: /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1343 XD_DEBUG_MESSAGE ("%s %s %s %u",
1344 XD_MESSAGE_TYPE_TO_STRING (mtype
),
1345 XD_OBJECT_TO_STRING (bus
),
1346 XD_OBJECT_TO_STRING (service
),
1350 /* Retrieve bus address. */
1351 connection
= xd_get_connection_address (bus
);
1353 /* Create the D-Bus message. */
1354 dmessage
= dbus_message_new (mtype
);
1355 if (dmessage
== NULL
)
1358 XD_SIGNAL1 (build_string ("Unable to create a new message"));
1361 if (STRINGP (service
))
1363 if (mtype
!= DBUS_MESSAGE_TYPE_SIGNAL
)
1364 /* Set destination. */
1366 if (!dbus_message_set_destination (dmessage
, SSDATA (service
)))
1369 XD_SIGNAL2 (build_string ("Unable to set the destination"),
1375 /* Set destination for unicast signals. */
1379 /* If it is the same unique name as we are registered at the
1380 bus or an unknown name, we regard it as broadcast message
1381 due to backward compatibility. */
1382 if (dbus_bus_name_has_owner (connection
, SSDATA (service
), NULL
))
1383 uname
= call2 (intern ("dbus-get-name-owner"), bus
, service
);
1388 && (strcmp (dbus_bus_get_unique_name (connection
), SSDATA (uname
))
1390 && (!dbus_message_set_destination (dmessage
, SSDATA (service
))))
1393 XD_SIGNAL2 (build_string ("Unable to set signal destination"),
1399 /* Set message parameters. */
1400 if ((mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1401 || (mtype
== DBUS_MESSAGE_TYPE_SIGNAL
))
1403 if ((!dbus_message_set_path (dmessage
, SSDATA (path
)))
1404 || (!dbus_message_set_interface (dmessage
, SSDATA (interface
)))
1405 || (!dbus_message_set_member (dmessage
, SSDATA (member
))))
1408 XD_SIGNAL1 (build_string ("Unable to set the message parameter"));
1412 else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1414 if (!dbus_message_set_reply_serial (dmessage
, serial
))
1417 XD_SIGNAL1 (build_string ("Unable to create a return message"));
1420 if ((mtype
== DBUS_MESSAGE_TYPE_ERROR
)
1421 && (!dbus_message_set_error_name (dmessage
, DBUS_ERROR_FAILED
)))
1424 XD_SIGNAL1 (build_string ("Unable to create a error message"));
1428 /* Check for timeout parameter. */
1429 if ((count
+2 <= nargs
) && (EQ ((args
[count
]), QCdbus_timeout
)))
1431 CHECK_NATNUM (args
[count
+1]);
1432 timeout
= min (XFASTINT (args
[count
+1]), INT_MAX
);
1436 /* Initialize parameter list of message. */
1437 dbus_message_iter_init_append (dmessage
, &iter
);
1439 /* Append parameters to the message. */
1440 for (; count
< nargs
; ++count
)
1442 dtype
= XD_OBJECT_TO_DBUS_TYPE (args
[count
]);
1443 if (XD_DBUS_TYPE_P (args
[count
]))
1445 XD_DEBUG_VALID_LISP_OBJECT_P (args
[count
]);
1446 XD_DEBUG_VALID_LISP_OBJECT_P (args
[count
+1]);
1447 XD_DEBUG_MESSAGE ("Parameter%"pD
"d %s %s", count
- 4,
1448 XD_OBJECT_TO_STRING (args
[count
]),
1449 XD_OBJECT_TO_STRING (args
[count
+1]));
1454 XD_DEBUG_VALID_LISP_OBJECT_P (args
[count
]);
1455 XD_DEBUG_MESSAGE ("Parameter%"pD
"d %s", count
- 4,
1456 XD_OBJECT_TO_STRING (args
[count
]));
1459 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1460 indication that there is no parent type. */
1461 xd_signature (signature
, dtype
, DBUS_TYPE_INVALID
, args
[count
]);
1463 xd_append_arg (dtype
, args
[count
], &iter
);
1466 if (!NILP (handler
))
1468 /* Send the message. The message is just added to the outgoing
1470 if (!dbus_connection_send_with_reply (connection
, dmessage
,
1474 XD_SIGNAL1 (build_string ("Cannot send message"));
1477 /* The result is the key in Vdbus_registered_objects_table. */
1478 serial
= dbus_message_get_serial (dmessage
);
1479 result
= list3 (QCdbus_registered_serial
,
1480 bus
, make_fixnum_or_float (serial
));
1482 /* Create a hash table entry. */
1483 Fputhash (result
, handler
, Vdbus_registered_objects_table
);
1487 /* Send the message. The message is just added to the outgoing
1489 if (!dbus_connection_send (connection
, dmessage
, NULL
))
1492 XD_SIGNAL1 (build_string ("Cannot send message"));
1498 XD_DEBUG_MESSAGE ("Message sent: %s", XD_OBJECT_TO_STRING (result
));
1501 dbus_message_unref (dmessage
);
1503 /* Return the result. */
1504 RETURN_UNGCPRO (result
);
1507 /* Read one queued incoming message of the D-Bus BUS.
1508 BUS is either a Lisp symbol, :system or :session, or a string denoting
1511 xd_read_message_1 (DBusConnection
*connection
, Lisp_Object bus
)
1513 Lisp_Object args
, key
, value
;
1514 struct gcpro gcpro1
;
1515 struct input_event event
;
1516 DBusMessage
*dmessage
;
1517 DBusMessageIter iter
;
1520 dbus_uint32_t serial
;
1521 unsigned int ui_serial
;
1522 const char *uname
, *path
, *interface
, *member
;
1524 dmessage
= dbus_connection_pop_message (connection
);
1526 /* Return if there is no queued message. */
1527 if (dmessage
== NULL
)
1530 /* Collect the parameters. */
1534 /* Loop over the resulting parameters. Construct a list. */
1535 if (dbus_message_iter_init (dmessage
, &iter
))
1537 while ((dtype
= dbus_message_iter_get_arg_type (&iter
))
1538 != DBUS_TYPE_INVALID
)
1540 args
= Fcons (xd_retrieve_arg (dtype
, &iter
), args
);
1541 dbus_message_iter_next (&iter
);
1543 /* The arguments are stored in reverse order. Reorder them. */
1544 args
= Fnreverse (args
);
1547 /* Read message type, message serial, unique name, object path,
1548 interface and member from the message. */
1549 mtype
= dbus_message_get_type (dmessage
);
1550 ui_serial
= serial
=
1551 ((mtype
== DBUS_MESSAGE_TYPE_METHOD_RETURN
)
1552 || (mtype
== DBUS_MESSAGE_TYPE_ERROR
))
1553 ? dbus_message_get_reply_serial (dmessage
)
1554 : dbus_message_get_serial (dmessage
);
1555 uname
= dbus_message_get_sender (dmessage
);
1556 path
= dbus_message_get_path (dmessage
);
1557 interface
= dbus_message_get_interface (dmessage
);
1558 member
= dbus_message_get_member (dmessage
);
1560 XD_DEBUG_MESSAGE ("Event received: %s %u %s %s %s %s %s",
1561 XD_MESSAGE_TYPE_TO_STRING (mtype
),
1562 ui_serial
, uname
, path
, interface
, member
,
1563 XD_OBJECT_TO_STRING (args
));
1565 if (mtype
== DBUS_MESSAGE_TYPE_INVALID
)
1568 else if ((mtype
== DBUS_MESSAGE_TYPE_METHOD_RETURN
)
1569 || (mtype
== DBUS_MESSAGE_TYPE_ERROR
))
1571 /* Search for a registered function of the message. */
1572 key
= list3 (QCdbus_registered_serial
, bus
,
1573 make_fixnum_or_float (serial
));
1574 value
= Fgethash (key
, Vdbus_registered_objects_table
, Qnil
);
1576 /* There shall be exactly one entry. Construct an event. */
1580 /* Remove the entry. */
1581 Fremhash (key
, Vdbus_registered_objects_table
);
1583 /* Construct an event. */
1585 event
.kind
= DBUS_EVENT
;
1586 event
.frame_or_window
= Qnil
;
1587 event
.arg
= Fcons (value
, args
);
1590 else /* DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_SIGNAL. */
1592 /* Vdbus_registered_objects_table requires non-nil interface and
1594 if ((interface
== NULL
) || (member
== NULL
))
1597 /* Search for a registered function of the message. */
1598 key
= list4 ((mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1599 ? QCdbus_registered_method
1600 : QCdbus_registered_signal
,
1601 bus
, build_string (interface
), build_string (member
));
1602 value
= Fgethash (key
, Vdbus_registered_objects_table
, Qnil
);
1604 /* Loop over the registered functions. Construct an event. */
1605 while (!NILP (value
))
1607 key
= CAR_SAFE (value
);
1608 /* key has the structure (UNAME SERVICE PATH HANDLER). */
1609 if (((uname
== NULL
)
1610 || (NILP (CAR_SAFE (key
)))
1611 || (strcmp (uname
, SSDATA (CAR_SAFE (key
))) == 0))
1613 || (NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))
1615 SSDATA (CAR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))
1617 && (!NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))))
1620 event
.kind
= DBUS_EVENT
;
1621 event
.frame_or_window
= Qnil
;
1623 = Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key
)))), args
);
1626 value
= CDR_SAFE (value
);
1633 /* Add type, serial, uname, path, interface and member to the event. */
1634 event
.arg
= Fcons ((member
== NULL
? Qnil
: build_string (member
)),
1636 event
.arg
= Fcons ((interface
== NULL
? Qnil
: build_string (interface
)),
1638 event
.arg
= Fcons ((path
== NULL
? Qnil
: build_string (path
)),
1640 event
.arg
= Fcons ((uname
== NULL
? Qnil
: build_string (uname
)),
1642 event
.arg
= Fcons (make_fixnum_or_float (serial
), event
.arg
);
1643 event
.arg
= Fcons (make_number (mtype
), event
.arg
);
1645 /* Add the bus symbol to the event. */
1646 event
.arg
= Fcons (bus
, event
.arg
);
1648 /* Store it into the input event queue. */
1649 kbd_buffer_store_event (&event
);
1651 XD_DEBUG_MESSAGE ("Event stored: %s", XD_OBJECT_TO_STRING (event
.arg
));
1655 dbus_message_unref (dmessage
);
1660 /* Read queued incoming messages of the D-Bus BUS.
1661 BUS is either a Lisp symbol, :system or :session, or a string denoting
1664 xd_read_message (Lisp_Object bus
)
1666 /* Retrieve bus address. */
1667 DBusConnection
*connection
= xd_get_connection_address (bus
);
1669 /* Non blocking read of the next available message. */
1670 dbus_connection_read_write (connection
, 0);
1672 while (dbus_connection_get_dispatch_status (connection
)
1673 != DBUS_DISPATCH_COMPLETE
)
1674 xd_read_message_1 (connection
, bus
);
1678 /* Callback called when something is ready to read or write. */
1680 xd_read_queued_messages (int fd
, void *data
)
1682 Lisp_Object busp
= xd_registered_buses
;
1683 Lisp_Object bus
= Qnil
;
1686 /* Find bus related to fd. */
1688 while (!NILP (busp
))
1690 key
= CAR_SAFE (CAR_SAFE (busp
));
1691 if ((SYMBOLP (key
) && XSYMBOL (key
) == data
)
1692 || (STRINGP (key
) && XSTRING (key
) == data
))
1694 busp
= CDR_SAFE (busp
);
1700 /* We ignore all Lisp errors during the call. */
1701 xd_in_read_queued_messages
= 1;
1702 internal_catch (Qdbus_error
, xd_read_message
, bus
);
1703 xd_in_read_queued_messages
= 0;
1708 init_dbusbind (void)
1710 /* We do not want to abort. */
1711 xputenv ("DBUS_FATAL_WARNINGS=0");
1715 syms_of_dbusbind (void)
1718 DEFSYM (Qdbus__init_bus
, "dbus--init-bus");
1719 defsubr (&Sdbus__init_bus
);
1721 DEFSYM (Qdbus_get_unique_name
, "dbus-get-unique-name");
1722 defsubr (&Sdbus_get_unique_name
);
1724 DEFSYM (Qdbus_message_internal
, "dbus-message-internal");
1725 defsubr (&Sdbus_message_internal
);
1727 /* D-Bus error symbol. */
1728 DEFSYM (Qdbus_error
, "dbus-error");
1729 Fput (Qdbus_error
, Qerror_conditions
,
1730 list2 (Qdbus_error
, Qerror
));
1731 Fput (Qdbus_error
, Qerror_message
,
1732 build_pure_c_string ("D-Bus error"));
1734 /* Lisp symbols of the system and session buses. */
1735 DEFSYM (QCdbus_system_bus
, ":system");
1736 DEFSYM (QCdbus_session_bus
, ":session");
1738 /* Lisp symbol for method call timeout. */
1739 DEFSYM (QCdbus_timeout
, ":timeout");
1741 /* Lisp symbols of D-Bus types. */
1742 DEFSYM (QCdbus_type_byte
, ":byte");
1743 DEFSYM (QCdbus_type_boolean
, ":boolean");
1744 DEFSYM (QCdbus_type_int16
, ":int16");
1745 DEFSYM (QCdbus_type_uint16
, ":uint16");
1746 DEFSYM (QCdbus_type_int32
, ":int32");
1747 DEFSYM (QCdbus_type_uint32
, ":uint32");
1748 DEFSYM (QCdbus_type_int64
, ":int64");
1749 DEFSYM (QCdbus_type_uint64
, ":uint64");
1750 DEFSYM (QCdbus_type_double
, ":double");
1751 DEFSYM (QCdbus_type_string
, ":string");
1752 DEFSYM (QCdbus_type_object_path
, ":object-path");
1753 DEFSYM (QCdbus_type_signature
, ":signature");
1754 #ifdef DBUS_TYPE_UNIX_FD
1755 DEFSYM (QCdbus_type_unix_fd
, ":unix-fd");
1757 DEFSYM (QCdbus_type_array
, ":array");
1758 DEFSYM (QCdbus_type_variant
, ":variant");
1759 DEFSYM (QCdbus_type_struct
, ":struct");
1760 DEFSYM (QCdbus_type_dict_entry
, ":dict-entry");
1762 /* Lisp symbols of objects in `dbus-registered-objects-table'. */
1763 DEFSYM (QCdbus_registered_serial
, ":serial");
1764 DEFSYM (QCdbus_registered_method
, ":method");
1765 DEFSYM (QCdbus_registered_signal
, ":signal");
1767 DEFVAR_LISP ("dbus-compiled-version",
1768 Vdbus_compiled_version
,
1769 doc
: /* The version of D-Bus Emacs is compiled against. */);
1770 #ifdef DBUS_VERSION_STRING
1771 Vdbus_compiled_version
= build_pure_c_string (DBUS_VERSION_STRING
);
1773 Vdbus_compiled_version
= Qnil
;
1776 DEFVAR_LISP ("dbus-runtime-version",
1777 Vdbus_runtime_version
,
1778 doc
: /* The version of D-Bus Emacs runs with. */);
1781 int major
, minor
, micro
;
1782 char s
[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
1783 dbus_get_version (&major
, &minor
, µ
);
1784 Vdbus_runtime_version
1785 = make_formatted_string (s
, "%d.%d.%d", major
, minor
, micro
);
1787 Vdbus_runtime_version
= Qnil
;
1791 DEFVAR_LISP ("dbus-message-type-invalid",
1792 Vdbus_message_type_invalid
,
1793 doc
: /* This value is never a valid message type. */);
1794 Vdbus_message_type_invalid
= make_number (DBUS_MESSAGE_TYPE_INVALID
);
1796 DEFVAR_LISP ("dbus-message-type-method-call",
1797 Vdbus_message_type_method_call
,
1798 doc
: /* Message type of a method call message. */);
1799 Vdbus_message_type_method_call
= make_number (DBUS_MESSAGE_TYPE_METHOD_CALL
);
1801 DEFVAR_LISP ("dbus-message-type-method-return",
1802 Vdbus_message_type_method_return
,
1803 doc
: /* Message type of a method return message. */);
1804 Vdbus_message_type_method_return
1805 = make_number (DBUS_MESSAGE_TYPE_METHOD_RETURN
);
1807 DEFVAR_LISP ("dbus-message-type-error",
1808 Vdbus_message_type_error
,
1809 doc
: /* Message type of an error reply message. */);
1810 Vdbus_message_type_error
= make_number (DBUS_MESSAGE_TYPE_ERROR
);
1812 DEFVAR_LISP ("dbus-message-type-signal",
1813 Vdbus_message_type_signal
,
1814 doc
: /* Message type of a signal message. */);
1815 Vdbus_message_type_signal
= make_number (DBUS_MESSAGE_TYPE_SIGNAL
);
1817 DEFVAR_LISP ("dbus-registered-objects-table",
1818 Vdbus_registered_objects_table
,
1819 doc
: /* Hash table of registered functions for D-Bus.
1821 There are two different uses of the hash table: for accessing
1822 registered interfaces properties, targeted by signals or method calls,
1823 and for calling handlers in case of non-blocking method call returns.
1825 In the first case, the key in the hash table is the list (TYPE BUS
1826 INTERFACE MEMBER). TYPE is one of the Lisp symbols `:method',
1827 `:signal' or `:property'. BUS is either a Lisp symbol, `:system' or
1828 `:session', or a string denoting the bus address. INTERFACE is a
1829 string which denotes a D-Bus interface, and MEMBER, also a string, is
1830 either a method, a signal or a property INTERFACE is offering. All
1831 arguments but BUS must not be nil.
1833 The value in the hash table is a list of quadruple lists \((UNAME
1834 SERVICE PATH OBJECT [RULE]) ...). SERVICE is the service name as
1835 registered, UNAME is the corresponding unique name. In case of
1836 registered methods and properties, UNAME is nil. PATH is the object
1837 path of the sending object. All of them can be nil, which means a
1838 wildcard then. OBJECT is either the handler to be called when a D-Bus
1839 message, which matches the key criteria, arrives (TYPE `:method' and
1840 `:signal'), or a cons cell containing the value of the property (TYPE
1843 For entries of type `:signal', there is also a fifth element RULE,
1844 which keeps the match string the signal is registered with.
1846 In the second case, the key in the hash table is the list (:serial BUS
1847 SERIAL). BUS is either a Lisp symbol, `:system' or `:session', or a
1848 string denoting the bus address. SERIAL is the serial number of the
1849 non-blocking method call, a reply is expected. Both arguments must
1850 not be nil. The value in the hash table is HANDLER, the function to
1851 be called when the D-Bus reply message arrives. */);
1852 Vdbus_registered_objects_table
= CALLN (Fmake_hash_table
, QCtest
, Qequal
);
1854 DEFVAR_LISP ("dbus-debug", Vdbus_debug
,
1855 doc
: /* If non-nil, debug messages of D-Bus bindings are raised. */);
1858 /* We can also set environment variable DBUS_VERBOSE=1 in order to
1859 see more traces. This requires libdbus-1 to be configured with
1860 --enable-verbose-mode. */
1865 /* Initialize internal objects. */
1866 xd_registered_buses
= Qnil
;
1867 staticpro (&xd_registered_buses
);
1869 Fprovide (intern_c_string ("dbusbind"), Qnil
);
1873 #endif /* HAVE_DBUS */