Make defvar affect the default binding outside of any let.
[emacs.git] / src / dbusbind.c
blob523544d56cada340749db599a61c94143474d9ac
1 /* Elisp bindings for D-Bus.
2 Copyright (C) 2007-2013 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/>. */
19 #include <config.h>
21 #ifdef HAVE_DBUS
22 #include <stdio.h>
23 #include <dbus/dbus.h>
25 #include "lisp.h"
26 #include "frame.h"
27 #include "termhooks.h"
28 #include "keyboard.h"
29 #include "process.h"
31 #ifndef DBUS_NUM_MESSAGE_TYPES
32 #define DBUS_NUM_MESSAGE_TYPES 5
33 #endif
36 /* Some platforms define the symbol "interface", but we want to use it
37 * as a variable name below. */
39 #ifdef interface
40 #undef interface
41 #endif
44 /* Subroutines. */
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;
67 #endif
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) \
90 do { \
91 if (xd_in_read_queued_messages) \
92 Fthrow (Qdbus_error, Qnil); \
93 else \
94 xsignal1 (Qdbus_error, arg); \
95 } while (0)
97 #define XD_SIGNAL2(arg1, arg2) \
98 do { \
99 if (xd_in_read_queued_messages) \
100 Fthrow (Qdbus_error, Qnil); \
101 else \
102 xsignal2 (Qdbus_error, arg1, arg2); \
103 } while (0)
105 #define XD_SIGNAL3(arg1, arg2, arg3) \
106 do { \
107 if (xd_in_read_queued_messages) \
108 Fthrow (Qdbus_error, Qnil); \
109 else \
110 xsignal3 (Qdbus_error, arg1, arg2, arg3); \
111 } while (0)
113 /* Raise a Lisp error from a D-Bus ERROR. */
114 #define XD_ERROR(error) \
115 do { \
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); \
121 XD_SIGNAL1 (err); \
122 } while (0)
124 /* Macros for debugging. In order to enable them, build with
125 "env MYCPPFLAGS='-DDBUS_DEBUG -Wall' make". */
126 #ifdef DBUS_DEBUG
127 #define XD_DEBUG_MESSAGE(...) \
128 do { \
129 char s[1024]; \
130 snprintf (s, sizeof s, __VA_ARGS__); \
131 if (!noninteractive) \
132 printf ("%s: %s\n", __func__, s); \
133 message ("%s: %s", __func__, s); \
134 } while (0)
135 #define XD_DEBUG_VALID_LISP_OBJECT_P(object) \
136 do { \
137 if (!valid_lisp_object_p (object)) \
139 XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__); \
140 XD_SIGNAL1 (build_string ("Assertion failure")); \
142 } while (0)
144 #else /* !DBUS_DEBUG */
145 # if __STDC_VERSION__ < 199901
146 # define XD_DEBUG_MESSAGE (void) /* Pre-C99 compilers cannot debug. */
147 # else
148 # define XD_DEBUG_MESSAGE(...) \
149 do { \
150 if (!NILP (Vdbus_debug)) \
152 char s[1024]; \
153 snprintf (s, sizeof s, __VA_ARGS__); \
154 message ("%s: %s", __func__, s); \
156 } while (0)
157 # endif
158 # define XD_DEBUG_VALID_LISP_OBJECT_P(object)
159 #endif
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))
165 #else
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))
181 #else
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))
195 #endif
196 #endif
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
200 a function. */
201 /* Determine the DBusType of a given Lisp symbol. OBJECT must be one
202 of the predefined D-Bus type symbols. */
203 static int
204 xd_symbol_to_dbus_type (Lisp_Object object)
206 return
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
221 #endif
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) \
244 : (CONSP (object)) \
245 ? ((XD_DBUS_TYPE_P (CAR_SAFE (object))) \
246 ? ((XD_BASIC_DBUS_TYPE (xd_symbol_to_dbus_type (CAR_SAFE (object)))) \
247 ? DBUS_TYPE_ARRAY \
248 : xd_symbol_to_dbus_type (CAR_SAFE (object))) \
249 : DBUS_TYPE_ARRAY) \
250 : DBUS_TYPE_INVALID)
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
257 messages. */
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
270 messages. */
271 #define XD_OBJECT_TO_STRING(object) \
272 SDATA (format2 ("%s", object, Qnil))
274 #define XD_DBUS_VALIDATE_BUS_ADDRESS(bus) \
275 do { \
276 char const *session_bus_address = getenv ("DBUS_SESSION_BUS_ADDRESS"); \
277 if (STRINGP (bus)) \
279 DBusAddressEntry **entries; \
280 int len; \
281 DBusError derror; \
282 dbus_error_init (&derror); \
283 if (!dbus_parse_address (SSDATA (bus), &entries, &len, &derror)) \
284 XD_ERROR (derror); \
285 /* Cleanup. */ \
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; \
295 else \
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); \
304 } while (0)
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) \
309 do { \
310 if (!NILP (object)) \
312 DBusError derror; \
313 CHECK_STRING (object); \
314 dbus_error_init (&derror); \
315 if (!func (SSDATA (object), &derror)) \
316 XD_ERROR (derror); \
317 /* Cleanup. */ \
318 dbus_error_free (&derror); \
320 } while (0)
321 #endif
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);
326 #else
327 #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \
328 if (!NILP (bus_name)) CHECK_STRING (bus_name);
329 #endif
331 #if HAVE_DBUS_VALIDATE_PATH
332 #define XD_DBUS_VALIDATE_PATH(path) \
333 XD_DBUS_VALIDATE_OBJECT(path, dbus_validate_path);
334 #else
335 #define XD_DBUS_VALIDATE_PATH(path) \
336 if (!NILP (path)) CHECK_STRING (path);
337 #endif
339 #if HAVE_DBUS_VALIDATE_INTERFACE
340 #define XD_DBUS_VALIDATE_INTERFACE(interface) \
341 XD_DBUS_VALIDATE_OBJECT(interface, dbus_validate_interface);
342 #else
343 #define XD_DBUS_VALIDATE_INTERFACE(interface) \
344 if (!NILP (interface)) CHECK_STRING (interface);
345 #endif
347 #if HAVE_DBUS_VALIDATE_MEMBER
348 #define XD_DBUS_VALIDATE_MEMBER(member) \
349 XD_DBUS_VALIDATE_OBJECT(member, dbus_validate_member);
350 #else
351 #define XD_DBUS_VALIDATE_MEMBER(member) \
352 if (!NILP (member)) CHECK_STRING (member);
353 #endif
355 /* Append to SIGNATURE a copy of X, making sure SIGNATURE does
356 not become too long. */
357 static void
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)
363 string_overflow ();
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. */
374 static void
375 xd_signature (char *signature, int dtype, int parent_type, Lisp_Object object)
377 int subtype;
378 Lisp_Object elt;
379 char const *subsig;
380 int subsiglen;
381 char x[DBUS_MAXIMUM_SIGNATURE_LENGTH];
383 elt = object;
385 switch (dtype)
387 case DBUS_TYPE_BYTE:
388 case DBUS_TYPE_UINT16:
389 CHECK_NATNUM (object);
390 sprintf (signature, "%c", dtype);
391 break;
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);
397 break;
399 case DBUS_TYPE_INT16:
400 CHECK_NUMBER (object);
401 sprintf (signature, "%c", dtype);
402 break;
404 case DBUS_TYPE_UINT32:
405 case DBUS_TYPE_UINT64:
406 #ifdef DBUS_TYPE_UNIX_FD
407 case DBUS_TYPE_UNIX_FD:
408 #endif
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);
414 break;
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);
421 break;
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. */
427 CHECK_CONS (object);
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
434 element type. */
435 if (NILP (elt))
437 subtype = DBUS_TYPE_STRING;
438 subsig = DBUS_TYPE_STRING_AS_STRING;
440 else
442 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
443 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
444 subsig = x;
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)));
455 while (!NILP (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))
465 string_overflow ();
466 break;
468 case DBUS_TYPE_VARIANT:
469 /* Check that there is exactly one list element. */
470 CHECK_CONS (object);
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);
481 break;
483 case DBUS_TYPE_STRUCT:
484 /* A struct list might contain any number of elements with
485 different types. No further check needed. */
486 CHECK_CONS (object);
488 elt = XD_NEXT_VALUE (elt);
490 /* Compose the signature from the elements. It is enclosed by
491 parentheses. */
492 sprintf (signature, "%c", DBUS_STRUCT_BEGIN_CHAR );
493 while (!NILP (elt))
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);
501 break;
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. */
507 CHECK_CONS (object);
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
514 curly braces. */
515 sprintf (signature, "%c", DBUS_DICT_ENTRY_BEGIN_CHAR);
517 /* First element. */
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);
538 break;
540 default:
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. */
548 static intmax_t
549 xd_extract_signed (Lisp_Object x, intmax_t lo, intmax_t hi)
551 CHECK_NUMBER_OR_FLOAT (x);
552 if (INTEGERP (x))
554 if (lo <= XINT (x) && XINT (x) <= hi)
555 return XINT (x);
557 else
559 double d = XFLOAT_DATA (x);
560 if (lo <= d && d <= hi)
562 intmax_t n = d;
563 if (n == d)
564 return n;
567 if (xd_in_read_queued_messages)
568 Fthrow (Qdbus_error, Qnil);
569 else
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. */
576 static uintmax_t
577 xd_extract_unsigned (Lisp_Object x, uintmax_t hi)
579 CHECK_NUMBER_OR_FLOAT (x);
580 if (INTEGERP (x))
582 if (0 <= XINT (x) && XINT (x) <= hi)
583 return XINT (x);
585 else
587 double d = XFLOAT_DATA (x);
588 if (0 <= d && d <= hi)
590 uintmax_t n = d;
591 if (n == d)
592 return n;
595 if (xd_in_read_queued_messages)
596 Fthrow (Qdbus_error, Qnil);
597 else
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. */
606 static void
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))
613 switch (dtype)
615 case DBUS_TYPE_BYTE:
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);
622 return;
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);
631 return;
634 case DBUS_TYPE_INT16:
636 dbus_int16_t val =
637 xd_extract_signed (object,
638 TYPE_MINIMUM (dbus_int16_t),
639 TYPE_MAXIMUM (dbus_int16_t));
640 int pval = val;
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);
644 return;
647 case DBUS_TYPE_UINT16:
649 dbus_uint16_t val =
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);
656 return;
659 case DBUS_TYPE_INT32:
661 dbus_int32_t val =
662 xd_extract_signed (object,
663 TYPE_MINIMUM (dbus_int32_t),
664 TYPE_MAXIMUM (dbus_int32_t));
665 int pval = val;
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);
669 return;
672 case DBUS_TYPE_UINT32:
673 #ifdef DBUS_TYPE_UNIX_FD
674 case DBUS_TYPE_UNIX_FD:
675 #endif
677 dbus_uint32_t val =
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);
684 return;
687 case DBUS_TYPE_INT64:
689 dbus_int64_t val =
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);
697 return;
700 case DBUS_TYPE_UINT64:
702 dbus_uint64_t val =
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);
709 return;
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);
718 return;
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);
734 return;
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. */
747 switch (dtype)
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
752 only. */
754 if (NILP (object))
755 /* If the array is empty, DBUS_TYPE_STRING is the default
756 element type. */
757 strcpy (signature, DBUS_TYPE_STRING_AS_STRING);
759 else
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));
772 else
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));
783 break;
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));
796 break;
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));
805 break;
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. */
830 static Lisp_Object
831 xd_retrieve_arg (int dtype, DBusMessageIter *iter)
834 switch (dtype)
836 case DBUS_TYPE_BYTE:
838 unsigned int val;
839 dbus_message_iter_get_basic (iter, &val);
840 val = val & 0xFF;
841 XD_DEBUG_MESSAGE ("%c %u", dtype, val);
842 return make_number (val);
845 case DBUS_TYPE_BOOLEAN:
847 dbus_bool_t val;
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:
855 dbus_int16_t val;
856 int pval;
857 dbus_message_iter_get_basic (iter, &val);
858 pval = val;
859 XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
860 return make_number (val);
863 case DBUS_TYPE_UINT16:
865 dbus_uint16_t val;
866 int pval;
867 dbus_message_iter_get_basic (iter, &val);
868 pval = val;
869 XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
870 return make_number (val);
873 case DBUS_TYPE_INT32:
875 dbus_int32_t val;
876 int pval;
877 dbus_message_iter_get_basic (iter, &val);
878 pval = 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:
886 #endif
888 dbus_uint32_t val;
889 unsigned int pval;
890 dbus_message_iter_get_basic (iter, &val);
891 pval = val;
892 XD_DEBUG_MESSAGE ("%c %u", dtype, pval);
893 return make_fixnum_or_float (val);
896 case DBUS_TYPE_INT64:
898 dbus_int64_t val;
899 printmax_t pval;
900 dbus_message_iter_get_basic (iter, &val);
901 pval = val;
902 XD_DEBUG_MESSAGE ("%c %"pMd, dtype, pval);
903 return make_fixnum_or_float (val);
906 case DBUS_TYPE_UINT64:
908 dbus_uint64_t val;
909 uprintmax_t pval;
910 dbus_message_iter_get_basic (iter, &val);
911 pval = val;
912 XD_DEBUG_MESSAGE ("%c %"pMd, dtype, pval);
913 return make_fixnum_or_float (val);
916 case DBUS_TYPE_DOUBLE:
918 double val;
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:
928 char *val;
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:
939 Lisp_Object result;
940 struct gcpro gcpro1;
941 DBusMessageIter subiter;
942 int subtype;
943 result = Qnil;
944 GCPRO1 (result);
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));
956 default:
957 XD_DEBUG_MESSAGE ("DBusType '%c' not supported", dtype);
958 return Qnil;
962 /* Return the number of references of the shared CONNECTION. */
963 static ptrdiff_t
964 xd_get_connection_references (DBusConnection *connection)
966 ptrdiff_t *refcount;
968 /* We cannot access the DBusConnection structure, it is not public.
969 But we know, that the reference counter is the first field in
970 that structure. */
971 refcount = (void *) &connection;
972 refcount = (void *) *refcount;
973 return *refcount;
976 /* Return D-Bus connection address. BUS is either a Lisp symbol,
977 :system or :session, or a string denoting the bus address. */
978 static DBusConnection *
979 xd_get_connection_address (Lisp_Object bus)
981 DBusConnection *connection;
982 Lisp_Object val;
984 val = CDR_SAFE (Fassoc (bus, xd_registered_buses));
985 if (NILP (val))
986 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
987 else
988 connection = (DBusConnection *) (intptr_t) XFASTINT (val);
990 if (!dbus_connection_get_is_connected (connection))
991 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
993 return connection;
996 /* Return the file descriptor for WATCH, -1 if not found. */
997 static int
998 xd_find_watch_fd (DBusWatch *watch)
1000 #if HAVE_DBUS_WATCH_GET_UNIX_FD
1001 /* TODO: Reverse these on w32, which prefers the opposite. */
1002 int fd = dbus_watch_get_unix_fd (watch);
1003 if (fd == -1)
1004 fd = dbus_watch_get_socket (watch);
1005 #else
1006 int fd = dbus_watch_get_fd (watch);
1007 #endif
1008 return fd;
1011 /* Prototype. */
1012 static void xd_read_queued_messages (int fd, void *data);
1014 /* Start monitoring WATCH for possible I/O. */
1015 static dbus_bool_t
1016 xd_add_watch (DBusWatch *watch, void *data)
1018 unsigned int flags = dbus_watch_get_flags (watch);
1019 int fd = xd_find_watch_fd (watch);
1021 XD_DEBUG_MESSAGE ("fd %d, write %d, enabled %d",
1022 fd, flags & DBUS_WATCH_WRITABLE,
1023 dbus_watch_get_enabled (watch));
1025 if (fd == -1)
1026 return FALSE;
1028 if (dbus_watch_get_enabled (watch))
1030 if (flags & DBUS_WATCH_WRITABLE)
1031 add_write_fd (fd, xd_read_queued_messages, data);
1032 if (flags & DBUS_WATCH_READABLE)
1033 add_read_fd (fd, xd_read_queued_messages, data);
1035 return TRUE;
1038 /* Stop monitoring WATCH for possible I/O.
1039 DATA is the used bus, either a string or QCdbus_system_bus or
1040 QCdbus_session_bus. */
1041 static void
1042 xd_remove_watch (DBusWatch *watch, void *data)
1044 unsigned int flags = dbus_watch_get_flags (watch);
1045 int fd = xd_find_watch_fd (watch);
1047 XD_DEBUG_MESSAGE ("fd %d", fd);
1049 if (fd == -1)
1050 return;
1052 /* Unset session environment. */
1053 #if 0
1054 if (XSYMBOL (QCdbus_session_bus) == data)
1056 XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
1057 unsetenv ("DBUS_SESSION_BUS_ADDRESS");
1059 #endif
1061 if (flags & DBUS_WATCH_WRITABLE)
1062 delete_write_fd (fd);
1063 if (flags & DBUS_WATCH_READABLE)
1064 delete_read_fd (fd);
1067 /* Toggle monitoring WATCH for possible I/O. */
1068 static void
1069 xd_toggle_watch (DBusWatch *watch, void *data)
1071 if (dbus_watch_get_enabled (watch))
1072 xd_add_watch (watch, data);
1073 else
1074 xd_remove_watch (watch, data);
1077 /* Close connection to D-Bus BUS. */
1078 static void
1079 xd_close_bus (Lisp_Object bus)
1081 DBusConnection *connection;
1082 Lisp_Object val;
1084 /* Check whether we are connected. */
1085 val = Fassoc (bus, xd_registered_buses);
1086 if (NILP (val))
1087 return;
1089 /* Retrieve bus address. */
1090 connection = xd_get_connection_address (bus);
1092 if (xd_get_connection_references (connection) == 1)
1094 /* Close connection, if there isn't another shared application. */
1095 XD_DEBUG_MESSAGE ("Close connection to bus %s",
1096 XD_OBJECT_TO_STRING (bus));
1097 dbus_connection_close (connection);
1099 xd_registered_buses = Fdelete (val, xd_registered_buses);
1102 else
1103 /* Decrement reference count. */
1104 dbus_connection_unref (connection);
1106 /* Return. */
1107 return;
1110 DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 2, 0,
1111 doc: /* Establish the connection to D-Bus BUS.
1113 BUS can be either the symbol `:system' or the symbol `:session', or it
1114 can be a string denoting the address of the corresponding bus. For
1115 the system and session buses, this function is called when loading
1116 `dbus.el', there is no need to call it again.
1118 The function returns a number, which counts the connections this Emacs
1119 session has established to the BUS under the same unique name (see
1120 `dbus-get-unique-name'). It depends on the libraries Emacs is linked
1121 with, and on the environment Emacs is running. For example, if Emacs
1122 is linked with the gtk toolkit, and it runs in a GTK-aware environment
1123 like Gnome, another connection might already be established.
1125 When PRIVATE is non-nil, a new connection is established instead of
1126 reusing an existing one. It results in a new unique name at the bus.
1127 This can be used, if it is necessary to distinguish from another
1128 connection used in the same Emacs process, like the one established by
1129 GTK+. It should be used with care for at least the `:system' and
1130 `:session' buses, because other Emacs Lisp packages might already use
1131 this connection to those buses. */)
1132 (Lisp_Object bus, Lisp_Object private)
1134 DBusConnection *connection;
1135 DBusError derror;
1136 Lisp_Object val;
1137 ptrdiff_t refcount;
1139 /* Check parameter. */
1140 XD_DBUS_VALIDATE_BUS_ADDRESS (bus);
1142 /* Close bus if it is already open. */
1143 xd_close_bus (bus);
1145 /* Check, whether we are still connected. */
1146 val = Fassoc (bus, xd_registered_buses);
1147 if (!NILP (val))
1149 connection = xd_get_connection_address (bus);
1150 dbus_connection_ref (connection);
1153 else
1155 /* Initialize. */
1156 dbus_error_init (&derror);
1158 /* Open the connection. */
1159 if (STRINGP (bus))
1160 if (NILP (private))
1161 connection = dbus_connection_open (SSDATA (bus), &derror);
1162 else
1163 connection = dbus_connection_open_private (SSDATA (bus), &derror);
1165 else
1166 if (NILP (private))
1167 connection = dbus_bus_get (EQ (bus, QCdbus_system_bus)
1168 ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION,
1169 &derror);
1170 else
1171 connection = dbus_bus_get_private (EQ (bus, QCdbus_system_bus)
1172 ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION,
1173 &derror);
1175 if (dbus_error_is_set (&derror))
1176 XD_ERROR (derror);
1178 if (connection == NULL)
1179 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
1181 /* If it is not the system or session bus, we must register
1182 ourselves. Otherwise, we have called dbus_bus_get, which has
1183 configured us to exit if the connection closes - we undo this
1184 setting. */
1185 if (STRINGP (bus))
1186 dbus_bus_register (connection, &derror);
1187 else
1188 dbus_connection_set_exit_on_disconnect (connection, FALSE);
1190 if (dbus_error_is_set (&derror))
1191 XD_ERROR (derror);
1193 /* Add the watch functions. We pass also the bus as data, in
1194 order to distinguish between the buses in xd_remove_watch. */
1195 if (!dbus_connection_set_watch_functions (connection,
1196 xd_add_watch,
1197 xd_remove_watch,
1198 xd_toggle_watch,
1199 SYMBOLP (bus)
1200 ? (void *) XSYMBOL (bus)
1201 : (void *) XSTRING (bus),
1202 NULL))
1203 XD_SIGNAL1 (build_string ("Cannot add watch functions"));
1205 /* Add bus to list of registered buses. */
1206 XSETFASTINT (val, (intptr_t) connection);
1207 xd_registered_buses = Fcons (Fcons (bus, val), xd_registered_buses);
1209 /* We do not want to abort. */
1210 xputenv ("DBUS_FATAL_WARNINGS=0");
1212 /* Cleanup. */
1213 dbus_error_free (&derror);
1216 /* Return reference counter. */
1217 refcount = xd_get_connection_references (connection);
1218 XD_DEBUG_MESSAGE ("Bus %s, Reference counter %"pD"d",
1219 XD_OBJECT_TO_STRING (bus), refcount);
1220 return make_number (refcount);
1223 DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name,
1224 1, 1, 0,
1225 doc: /* Return the unique name of Emacs registered at D-Bus BUS. */)
1226 (Lisp_Object bus)
1228 DBusConnection *connection;
1229 const char *name;
1231 /* Check parameter. */
1232 XD_DBUS_VALIDATE_BUS_ADDRESS (bus);
1234 /* Retrieve bus address. */
1235 connection = xd_get_connection_address (bus);
1237 /* Request the name. */
1238 name = dbus_bus_get_unique_name (connection);
1239 if (name == NULL)
1240 XD_SIGNAL1 (build_string ("No unique name available"));
1242 /* Return. */
1243 return build_string (name);
1246 DEFUN ("dbus-message-internal", Fdbus_message_internal, Sdbus_message_internal,
1247 4, MANY, 0,
1248 doc: /* Send a D-Bus message.
1249 This is an internal function, it shall not be used outside dbus.el.
1251 The following usages are expected:
1253 `dbus-call-method', `dbus-call-method-asynchronously':
1254 \(dbus-message-internal
1255 dbus-message-type-method-call BUS SERVICE PATH INTERFACE METHOD HANDLER
1256 &optional :timeout TIMEOUT &rest ARGS)
1258 `dbus-send-signal':
1259 \(dbus-message-internal
1260 dbus-message-type-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS)
1262 `dbus-method-return-internal':
1263 \(dbus-message-internal
1264 dbus-message-type-method-return BUS SERVICE SERIAL &rest ARGS)
1266 `dbus-method-error-internal':
1267 \(dbus-message-internal
1268 dbus-message-type-error BUS SERVICE SERIAL &rest ARGS)
1270 usage: (dbus-message-internal &rest REST) */)
1271 (ptrdiff_t nargs, Lisp_Object *args)
1273 Lisp_Object message_type, bus, service, handler;
1274 Lisp_Object path = Qnil;
1275 Lisp_Object interface = Qnil;
1276 Lisp_Object member = Qnil;
1277 Lisp_Object result;
1278 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
1279 DBusConnection *connection;
1280 DBusMessage *dmessage;
1281 DBusMessageIter iter;
1282 int dtype;
1283 int mtype;
1284 dbus_uint32_t serial = 0;
1285 unsigned int ui_serial;
1286 int timeout = -1;
1287 ptrdiff_t count;
1288 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1290 /* Initialize parameters. */
1291 message_type = args[0];
1292 bus = args[1];
1293 service = args[2];
1294 handler = Qnil;
1296 CHECK_NATNUM (message_type);
1297 if (! (DBUS_MESSAGE_TYPE_INVALID < XFASTINT (message_type)
1298 && XFASTINT (message_type) < DBUS_NUM_MESSAGE_TYPES))
1299 XD_SIGNAL2 (build_string ("Invalid message type"), message_type);
1300 mtype = XFASTINT (message_type);
1302 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1303 || (mtype == DBUS_MESSAGE_TYPE_SIGNAL))
1305 path = args[3];
1306 interface = args[4];
1307 member = args[5];
1308 if (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1309 handler = args[6];
1310 count = (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) ? 7 : 6;
1312 else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1314 serial = xd_extract_unsigned (args[3], TYPE_MAXIMUM (dbus_uint32_t));
1315 count = 4;
1318 /* Check parameters. */
1319 XD_DBUS_VALIDATE_BUS_ADDRESS (bus);
1320 XD_DBUS_VALIDATE_BUS_NAME (service);
1321 if (nargs < count)
1322 xsignal2 (Qwrong_number_of_arguments,
1323 Qdbus_message_internal,
1324 make_number (nargs));
1326 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1327 || (mtype == DBUS_MESSAGE_TYPE_SIGNAL))
1329 XD_DBUS_VALIDATE_PATH (path);
1330 XD_DBUS_VALIDATE_INTERFACE (interface);
1331 XD_DBUS_VALIDATE_MEMBER (member);
1332 if (!NILP (handler) && (!FUNCTIONP (handler)))
1333 wrong_type_argument (Qinvalid_function, handler);
1336 /* Protect Lisp variables. */
1337 GCPRO6 (bus, service, path, interface, member, handler);
1339 /* Trace parameters. */
1340 switch (mtype)
1342 case DBUS_MESSAGE_TYPE_METHOD_CALL:
1343 XD_DEBUG_MESSAGE ("%s %s %s %s %s %s %s",
1344 XD_MESSAGE_TYPE_TO_STRING (mtype),
1345 XD_OBJECT_TO_STRING (bus),
1346 XD_OBJECT_TO_STRING (service),
1347 XD_OBJECT_TO_STRING (path),
1348 XD_OBJECT_TO_STRING (interface),
1349 XD_OBJECT_TO_STRING (member),
1350 XD_OBJECT_TO_STRING (handler));
1351 break;
1352 case DBUS_MESSAGE_TYPE_SIGNAL:
1353 XD_DEBUG_MESSAGE ("%s %s %s %s %s %s",
1354 XD_MESSAGE_TYPE_TO_STRING (mtype),
1355 XD_OBJECT_TO_STRING (bus),
1356 XD_OBJECT_TO_STRING (service),
1357 XD_OBJECT_TO_STRING (path),
1358 XD_OBJECT_TO_STRING (interface),
1359 XD_OBJECT_TO_STRING (member));
1360 break;
1361 default: /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1362 ui_serial = serial;
1363 XD_DEBUG_MESSAGE ("%s %s %s %u",
1364 XD_MESSAGE_TYPE_TO_STRING (mtype),
1365 XD_OBJECT_TO_STRING (bus),
1366 XD_OBJECT_TO_STRING (service),
1367 ui_serial);
1370 /* Retrieve bus address. */
1371 connection = xd_get_connection_address (bus);
1373 /* Create the D-Bus message. */
1374 dmessage = dbus_message_new (mtype);
1375 if (dmessage == NULL)
1377 UNGCPRO;
1378 XD_SIGNAL1 (build_string ("Unable to create a new message"));
1381 if (STRINGP (service))
1383 if (mtype != DBUS_MESSAGE_TYPE_SIGNAL)
1384 /* Set destination. */
1386 if (!dbus_message_set_destination (dmessage, SSDATA (service)))
1388 UNGCPRO;
1389 XD_SIGNAL2 (build_string ("Unable to set the destination"),
1390 service);
1394 else
1395 /* Set destination for unicast signals. */
1397 Lisp_Object uname;
1399 /* If it is the same unique name as we are registered at the
1400 bus or an unknown name, we regard it as broadcast message
1401 due to backward compatibility. */
1402 if (dbus_bus_name_has_owner (connection, SSDATA (service), NULL))
1403 uname = call2 (intern ("dbus-get-name-owner"), bus, service);
1404 else
1405 uname = Qnil;
1407 if (STRINGP (uname)
1408 && (strcmp (dbus_bus_get_unique_name (connection), SSDATA (uname))
1409 != 0)
1410 && (!dbus_message_set_destination (dmessage, SSDATA (service))))
1412 UNGCPRO;
1413 XD_SIGNAL2 (build_string ("Unable to set signal destination"),
1414 service);
1419 /* Set message parameters. */
1420 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1421 || (mtype == DBUS_MESSAGE_TYPE_SIGNAL))
1423 if ((!dbus_message_set_path (dmessage, SSDATA (path)))
1424 || (!dbus_message_set_interface (dmessage, SSDATA (interface)))
1425 || (!dbus_message_set_member (dmessage, SSDATA (member))))
1427 UNGCPRO;
1428 XD_SIGNAL1 (build_string ("Unable to set the message parameter"));
1432 else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1434 if (!dbus_message_set_reply_serial (dmessage, serial))
1436 UNGCPRO;
1437 XD_SIGNAL1 (build_string ("Unable to create a return message"));
1440 if ((mtype == DBUS_MESSAGE_TYPE_ERROR)
1441 && (!dbus_message_set_error_name (dmessage, DBUS_ERROR_FAILED)))
1443 UNGCPRO;
1444 XD_SIGNAL1 (build_string ("Unable to create a error message"));
1448 /* Check for timeout parameter. */
1449 if ((count+2 <= nargs) && (EQ ((args[count]), QCdbus_timeout)))
1451 CHECK_NATNUM (args[count+1]);
1452 timeout = min (XFASTINT (args[count+1]), INT_MAX);
1453 count = count+2;
1456 /* Initialize parameter list of message. */
1457 dbus_message_iter_init_append (dmessage, &iter);
1459 /* Append parameters to the message. */
1460 for (; count < nargs; ++count)
1462 dtype = XD_OBJECT_TO_DBUS_TYPE (args[count]);
1463 if (XD_DBUS_TYPE_P (args[count]))
1465 XD_DEBUG_VALID_LISP_OBJECT_P (args[count]);
1466 XD_DEBUG_VALID_LISP_OBJECT_P (args[count+1]);
1467 XD_DEBUG_MESSAGE ("Parameter%"pD"d %s %s", count - 4,
1468 XD_OBJECT_TO_STRING (args[count]),
1469 XD_OBJECT_TO_STRING (args[count+1]));
1470 ++count;
1472 else
1474 XD_DEBUG_VALID_LISP_OBJECT_P (args[count]);
1475 XD_DEBUG_MESSAGE ("Parameter%"pD"d %s", count - 4,
1476 XD_OBJECT_TO_STRING (args[count]));
1479 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1480 indication that there is no parent type. */
1481 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[count]);
1483 xd_append_arg (dtype, args[count], &iter);
1486 if (!NILP (handler))
1488 /* Send the message. The message is just added to the outgoing
1489 message queue. */
1490 if (!dbus_connection_send_with_reply (connection, dmessage,
1491 NULL, timeout))
1493 UNGCPRO;
1494 XD_SIGNAL1 (build_string ("Cannot send message"));
1497 /* The result is the key in Vdbus_registered_objects_table. */
1498 serial = dbus_message_get_serial (dmessage);
1499 result = list3 (QCdbus_registered_serial,
1500 bus, make_fixnum_or_float (serial));
1502 /* Create a hash table entry. */
1503 Fputhash (result, handler, Vdbus_registered_objects_table);
1505 else
1507 /* Send the message. The message is just added to the outgoing
1508 message queue. */
1509 if (!dbus_connection_send (connection, dmessage, NULL))
1511 UNGCPRO;
1512 XD_SIGNAL1 (build_string ("Cannot send message"));
1515 result = Qnil;
1518 XD_DEBUG_MESSAGE ("Message sent: %s", XD_OBJECT_TO_STRING (result));
1520 /* Cleanup. */
1521 dbus_message_unref (dmessage);
1523 /* Return the result. */
1524 RETURN_UNGCPRO (result);
1527 /* Read one queued incoming message of the D-Bus BUS.
1528 BUS is either a Lisp symbol, :system or :session, or a string denoting
1529 the bus address. */
1530 static void
1531 xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
1533 Lisp_Object args, key, value;
1534 struct gcpro gcpro1;
1535 struct input_event event;
1536 DBusMessage *dmessage;
1537 DBusMessageIter iter;
1538 int dtype;
1539 int mtype;
1540 dbus_uint32_t serial;
1541 unsigned int ui_serial;
1542 const char *uname, *path, *interface, *member;
1544 dmessage = dbus_connection_pop_message (connection);
1546 /* Return if there is no queued message. */
1547 if (dmessage == NULL)
1548 return;
1550 /* Collect the parameters. */
1551 args = Qnil;
1552 GCPRO1 (args);
1554 /* Loop over the resulting parameters. Construct a list. */
1555 if (dbus_message_iter_init (dmessage, &iter))
1557 while ((dtype = dbus_message_iter_get_arg_type (&iter))
1558 != DBUS_TYPE_INVALID)
1560 args = Fcons (xd_retrieve_arg (dtype, &iter), args);
1561 dbus_message_iter_next (&iter);
1563 /* The arguments are stored in reverse order. Reorder them. */
1564 args = Fnreverse (args);
1567 /* Read message type, message serial, unique name, object path,
1568 interface and member from the message. */
1569 mtype = dbus_message_get_type (dmessage);
1570 ui_serial = serial =
1571 ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1572 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1573 ? dbus_message_get_reply_serial (dmessage)
1574 : dbus_message_get_serial (dmessage);
1575 uname = dbus_message_get_sender (dmessage);
1576 path = dbus_message_get_path (dmessage);
1577 interface = dbus_message_get_interface (dmessage);
1578 member = dbus_message_get_member (dmessage);
1580 XD_DEBUG_MESSAGE ("Event received: %s %u %s %s %s %s %s",
1581 XD_MESSAGE_TYPE_TO_STRING (mtype),
1582 ui_serial, uname, path, interface, member,
1583 XD_OBJECT_TO_STRING (args));
1585 if (mtype == DBUS_MESSAGE_TYPE_INVALID)
1586 goto cleanup;
1588 else if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1589 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1591 /* Search for a registered function of the message. */
1592 key = list3 (QCdbus_registered_serial, bus,
1593 make_fixnum_or_float (serial));
1594 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1596 /* There shall be exactly one entry. Construct an event. */
1597 if (NILP (value))
1598 goto cleanup;
1600 /* Remove the entry. */
1601 Fremhash (key, Vdbus_registered_objects_table);
1603 /* Construct an event. */
1604 EVENT_INIT (event);
1605 event.kind = DBUS_EVENT;
1606 event.frame_or_window = Qnil;
1607 event.arg = Fcons (value, args);
1610 else /* DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_SIGNAL. */
1612 /* Vdbus_registered_objects_table requires non-nil interface and
1613 member. */
1614 if ((interface == NULL) || (member == NULL))
1615 goto cleanup;
1617 /* Search for a registered function of the message. */
1618 key = list4 ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1619 ? QCdbus_registered_method
1620 : QCdbus_registered_signal,
1621 bus, build_string (interface), build_string (member));
1622 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1624 /* Loop over the registered functions. Construct an event. */
1625 while (!NILP (value))
1627 key = CAR_SAFE (value);
1628 /* key has the structure (UNAME SERVICE PATH HANDLER). */
1629 if (((uname == NULL)
1630 || (NILP (CAR_SAFE (key)))
1631 || (strcmp (uname, SSDATA (CAR_SAFE (key))) == 0))
1632 && ((path == NULL)
1633 || (NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (key)))))
1634 || (strcmp (path,
1635 SSDATA (CAR_SAFE (CDR_SAFE (CDR_SAFE (key)))))
1636 == 0))
1637 && (!NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))))))
1639 EVENT_INIT (event);
1640 event.kind = DBUS_EVENT;
1641 event.frame_or_window = Qnil;
1642 event.arg
1643 = Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))), args);
1644 break;
1646 value = CDR_SAFE (value);
1649 if (NILP (value))
1650 goto cleanup;
1653 /* Add type, serial, uname, path, interface and member to the event. */
1654 event.arg = Fcons ((member == NULL ? Qnil : build_string (member)),
1655 event.arg);
1656 event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)),
1657 event.arg);
1658 event.arg = Fcons ((path == NULL ? Qnil : build_string (path)),
1659 event.arg);
1660 event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)),
1661 event.arg);
1662 event.arg = Fcons (make_fixnum_or_float (serial), event.arg);
1663 event.arg = Fcons (make_number (mtype), event.arg);
1665 /* Add the bus symbol to the event. */
1666 event.arg = Fcons (bus, event.arg);
1668 /* Store it into the input event queue. */
1669 kbd_buffer_store_event (&event);
1671 XD_DEBUG_MESSAGE ("Event stored: %s", XD_OBJECT_TO_STRING (event.arg));
1673 /* Cleanup. */
1674 cleanup:
1675 dbus_message_unref (dmessage);
1677 UNGCPRO;
1680 /* Read queued incoming messages of the D-Bus BUS.
1681 BUS is either a Lisp symbol, :system or :session, or a string denoting
1682 the bus address. */
1683 static Lisp_Object
1684 xd_read_message (Lisp_Object bus)
1686 /* Retrieve bus address. */
1687 DBusConnection *connection = xd_get_connection_address (bus);
1689 /* Non blocking read of the next available message. */
1690 dbus_connection_read_write (connection, 0);
1692 while (dbus_connection_get_dispatch_status (connection)
1693 != DBUS_DISPATCH_COMPLETE)
1694 xd_read_message_1 (connection, bus);
1695 return Qnil;
1698 /* Callback called when something is ready to read or write. */
1699 static void
1700 xd_read_queued_messages (int fd, void *data)
1702 Lisp_Object busp = xd_registered_buses;
1703 Lisp_Object bus = Qnil;
1704 Lisp_Object key;
1706 /* Find bus related to fd. */
1707 if (data != NULL)
1708 while (!NILP (busp))
1710 key = CAR_SAFE (CAR_SAFE (busp));
1711 if ((SYMBOLP (key) && XSYMBOL (key) == data)
1712 || (STRINGP (key) && XSTRING (key) == data))
1713 bus = key;
1714 busp = CDR_SAFE (busp);
1717 if (NILP (bus))
1718 return;
1720 /* We ignore all Lisp errors during the call. */
1721 xd_in_read_queued_messages = 1;
1722 internal_catch (Qdbus_error, xd_read_message, bus);
1723 xd_in_read_queued_messages = 0;
1727 void
1728 syms_of_dbusbind (void)
1731 DEFSYM (Qdbus_init_bus, "dbus-init-bus");
1732 defsubr (&Sdbus_init_bus);
1734 DEFSYM (Qdbus_get_unique_name, "dbus-get-unique-name");
1735 defsubr (&Sdbus_get_unique_name);
1737 DEFSYM (Qdbus_message_internal, "dbus-message-internal");
1738 defsubr (&Sdbus_message_internal);
1740 DEFSYM (Qdbus_error, "dbus-error");
1741 Fput (Qdbus_error, Qerror_conditions,
1742 list2 (Qdbus_error, Qerror));
1743 Fput (Qdbus_error, Qerror_message,
1744 build_pure_c_string ("D-Bus error"));
1746 DEFSYM (QCdbus_system_bus, ":system");
1747 DEFSYM (QCdbus_session_bus, ":session");
1748 DEFSYM (QCdbus_timeout, ":timeout");
1749 DEFSYM (QCdbus_type_byte, ":byte");
1750 DEFSYM (QCdbus_type_boolean, ":boolean");
1751 DEFSYM (QCdbus_type_int16, ":int16");
1752 DEFSYM (QCdbus_type_uint16, ":uint16");
1753 DEFSYM (QCdbus_type_int32, ":int32");
1754 DEFSYM (QCdbus_type_uint32, ":uint32");
1755 DEFSYM (QCdbus_type_int64, ":int64");
1756 DEFSYM (QCdbus_type_uint64, ":uint64");
1757 DEFSYM (QCdbus_type_double, ":double");
1758 DEFSYM (QCdbus_type_string, ":string");
1759 DEFSYM (QCdbus_type_object_path, ":object-path");
1760 DEFSYM (QCdbus_type_signature, ":signature");
1761 #ifdef DBUS_TYPE_UNIX_FD
1762 DEFSYM (QCdbus_type_unix_fd, ":unix-fd");
1763 #endif
1764 DEFSYM (QCdbus_type_array, ":array");
1765 DEFSYM (QCdbus_type_variant, ":variant");
1766 DEFSYM (QCdbus_type_struct, ":struct");
1767 DEFSYM (QCdbus_type_dict_entry, ":dict-entry");
1768 DEFSYM (QCdbus_registered_serial, ":serial");
1769 DEFSYM (QCdbus_registered_method, ":method");
1770 DEFSYM (QCdbus_registered_signal, ":signal");
1772 DEFVAR_LISP ("dbus-compiled-version",
1773 Vdbus_compiled_version,
1774 doc: /* The version of D-Bus Emacs is compiled against. */);
1775 #ifdef DBUS_VERSION_STRING
1776 Vdbus_compiled_version = build_pure_c_string (DBUS_VERSION_STRING);
1777 #else
1778 Vdbus_compiled_version = Qnil;
1779 #endif
1781 DEFVAR_LISP ("dbus-runtime-version",
1782 Vdbus_runtime_version,
1783 doc: /* The version of D-Bus Emacs runs with. */);
1785 #ifdef DBUS_VERSION
1786 int major, minor, micro;
1787 char s[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
1788 dbus_get_version (&major, &minor, &micro);
1789 Vdbus_runtime_version
1790 = make_formatted_string (s, "%d.%d.%d", major, minor, micro);
1791 #else
1792 Vdbus_runtime_version = Qnil;
1793 #endif
1796 DEFVAR_LISP ("dbus-message-type-invalid",
1797 Vdbus_message_type_invalid,
1798 doc: /* This value is never a valid message type. */);
1799 Vdbus_message_type_invalid = make_number (DBUS_MESSAGE_TYPE_INVALID);
1801 DEFVAR_LISP ("dbus-message-type-method-call",
1802 Vdbus_message_type_method_call,
1803 doc: /* Message type of a method call message. */);
1804 Vdbus_message_type_method_call = make_number (DBUS_MESSAGE_TYPE_METHOD_CALL);
1806 DEFVAR_LISP ("dbus-message-type-method-return",
1807 Vdbus_message_type_method_return,
1808 doc: /* Message type of a method return message. */);
1809 Vdbus_message_type_method_return
1810 = make_number (DBUS_MESSAGE_TYPE_METHOD_RETURN);
1812 DEFVAR_LISP ("dbus-message-type-error",
1813 Vdbus_message_type_error,
1814 doc: /* Message type of an error reply message. */);
1815 Vdbus_message_type_error = make_number (DBUS_MESSAGE_TYPE_ERROR);
1817 DEFVAR_LISP ("dbus-message-type-signal",
1818 Vdbus_message_type_signal,
1819 doc: /* Message type of a signal message. */);
1820 Vdbus_message_type_signal = make_number (DBUS_MESSAGE_TYPE_SIGNAL);
1822 DEFVAR_LISP ("dbus-registered-objects-table",
1823 Vdbus_registered_objects_table,
1824 doc: /* Hash table of registered functions for D-Bus.
1826 There are two different uses of the hash table: for accessing
1827 registered interfaces properties, targeted by signals or method calls,
1828 and for calling handlers in case of non-blocking method call returns.
1830 In the first case, the key in the hash table is the list (TYPE BUS
1831 INTERFACE MEMBER). TYPE is one of the Lisp symbols `:method',
1832 `:signal' or `:property'. BUS is either a Lisp symbol, `:system' or
1833 `:session', or a string denoting the bus address. INTERFACE is a
1834 string which denotes a D-Bus interface, and MEMBER, also a string, is
1835 either a method, a signal or a property INTERFACE is offering. All
1836 arguments but BUS must not be nil.
1838 The value in the hash table is a list of quadruple lists \((UNAME
1839 SERVICE PATH OBJECT [RULE]) ...). SERVICE is the service name as
1840 registered, UNAME is the corresponding unique name. In case of
1841 registered methods and properties, UNAME is nil. PATH is the object
1842 path of the sending object. All of them can be nil, which means a
1843 wildcard then. OBJECT is either the handler to be called when a D-Bus
1844 message, which matches the key criteria, arrives (TYPE `:method' and
1845 `:signal'), or a cons cell containing the value of the property (TYPE
1846 `:property').
1848 For entries of type `:signal', there is also a fifth element RULE,
1849 which keeps the match string the signal is registered with.
1851 In the second case, the key in the hash table is the list (:serial BUS
1852 SERIAL). BUS is either a Lisp symbol, `:system' or `:session', or a
1853 string denoting the bus address. SERIAL is the serial number of the
1854 non-blocking method call, a reply is expected. Both arguments must
1855 not be nil. The value in the hash table is HANDLER, the function to
1856 be called when the D-Bus reply message arrives. */);
1858 Lisp_Object args[2];
1859 args[0] = QCtest;
1860 args[1] = Qequal;
1861 Vdbus_registered_objects_table = Fmake_hash_table (2, args);
1864 DEFVAR_LISP ("dbus-debug", Vdbus_debug,
1865 doc: /* If non-nil, debug messages of D-Bus bindings are raised. */);
1866 #ifdef DBUS_DEBUG
1867 Vdbus_debug = Qt;
1868 /* We can also set environment variable DBUS_VERBOSE=1 in order to
1869 see more traces. This requires libdbus-1 to be configured with
1870 --enable-verbose-mode. */
1871 #else
1872 Vdbus_debug = Qnil;
1873 #endif
1875 /* Initialize internal objects. */
1876 xd_registered_buses = Qnil;
1877 staticpro (&xd_registered_buses);
1879 Fprovide (intern_c_string ("dbusbind"), Qnil);
1883 #endif /* HAVE_DBUS */