1 /* Elisp bindings for D-Bus.
2 Copyright (C) 2007-2012 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
37 static Lisp_Object Qdbus_init_bus
;
38 static Lisp_Object Qdbus_get_unique_name
;
39 static Lisp_Object Qdbus_message_internal
;
41 /* D-Bus error symbol. */
42 static Lisp_Object Qdbus_error
;
44 /* Lisp symbols of the system and session buses. */
45 static Lisp_Object QCdbus_system_bus
, QCdbus_session_bus
;
47 /* Lisp symbol for method call timeout. */
48 static Lisp_Object QCdbus_timeout
;
50 /* Lisp symbols of D-Bus types. */
51 static Lisp_Object QCdbus_type_byte
, QCdbus_type_boolean
;
52 static Lisp_Object QCdbus_type_int16
, QCdbus_type_uint16
;
53 static Lisp_Object QCdbus_type_int32
, QCdbus_type_uint32
;
54 static Lisp_Object QCdbus_type_int64
, QCdbus_type_uint64
;
55 static Lisp_Object QCdbus_type_double
, QCdbus_type_string
;
56 static Lisp_Object QCdbus_type_object_path
, QCdbus_type_signature
;
57 #ifdef DBUS_TYPE_UNIX_FD
58 static Lisp_Object QCdbus_type_unix_fd
;
60 static Lisp_Object QCdbus_type_array
, QCdbus_type_variant
;
61 static Lisp_Object QCdbus_type_struct
, QCdbus_type_dict_entry
;
63 /* Lisp symbols of objects in `dbus-registered-objects-table'. */
64 static Lisp_Object QCdbus_registered_serial
, QCdbus_registered_method
;
65 static Lisp_Object QCdbus_registered_signal
;
67 /* Whether we are reading a D-Bus event. */
68 static int xd_in_read_queued_messages
= 0;
71 /* We use "xd_" and "XD_" as prefix for all internal symbols, because
72 we don't want to poison other namespaces with "dbus_". */
74 /* Raise a signal. If we are reading events, we cannot signal; we
75 throw to xd_read_queued_messages then. */
76 #define XD_SIGNAL1(arg) \
78 if (xd_in_read_queued_messages) \
79 Fthrow (Qdbus_error, Qnil); \
81 xsignal1 (Qdbus_error, arg); \
84 #define XD_SIGNAL2(arg1, arg2) \
86 if (xd_in_read_queued_messages) \
87 Fthrow (Qdbus_error, Qnil); \
89 xsignal2 (Qdbus_error, arg1, arg2); \
92 #define XD_SIGNAL3(arg1, arg2, arg3) \
94 if (xd_in_read_queued_messages) \
95 Fthrow (Qdbus_error, Qnil); \
97 xsignal3 (Qdbus_error, arg1, arg2, arg3); \
100 /* Raise a Lisp error from a D-Bus ERROR. */
101 #define XD_ERROR(error) \
103 /* Remove the trailing newline. */ \
104 char const *mess = error.message; \
105 char const *nl = strchr (mess, '\n'); \
106 Lisp_Object err = make_string (mess, nl ? nl - mess : strlen (mess)); \
107 dbus_error_free (&error); \
111 /* Macros for debugging. In order to enable them, build with
112 "env MYCPPFLAGS='-DDBUS_DEBUG -Wall' make". */
114 #define XD_DEBUG_MESSAGE(...) \
117 snprintf (s, sizeof s, __VA_ARGS__); \
118 printf ("%s: %s\n", __func__, s); \
119 message ("%s: %s", __func__, s); \
121 #define XD_DEBUG_VALID_LISP_OBJECT_P(object) \
123 if (!valid_lisp_object_p (object)) \
125 XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__); \
126 XD_SIGNAL1 (build_string ("Assertion failure")); \
130 #else /* !DBUS_DEBUG */
131 #define XD_DEBUG_MESSAGE(...) \
133 if (!NILP (Vdbus_debug)) \
136 snprintf (s, sizeof s, __VA_ARGS__); \
137 message ("%s: %s", __func__, s); \
140 #define XD_DEBUG_VALID_LISP_OBJECT_P(object)
143 /* Check whether TYPE is a basic DBusType. */
144 #ifdef DBUS_TYPE_UNIX_FD
145 #define XD_BASIC_DBUS_TYPE(type) \
146 ((type == DBUS_TYPE_BYTE) \
147 || (type == DBUS_TYPE_BOOLEAN) \
148 || (type == DBUS_TYPE_INT16) \
149 || (type == DBUS_TYPE_UINT16) \
150 || (type == DBUS_TYPE_INT32) \
151 || (type == DBUS_TYPE_UINT32) \
152 || (type == DBUS_TYPE_INT64) \
153 || (type == DBUS_TYPE_UINT64) \
154 || (type == DBUS_TYPE_DOUBLE) \
155 || (type == DBUS_TYPE_STRING) \
156 || (type == DBUS_TYPE_OBJECT_PATH) \
157 || (type == DBUS_TYPE_SIGNATURE) \
158 || (type == DBUS_TYPE_UNIX_FD))
160 #define XD_BASIC_DBUS_TYPE(type) \
161 ((type == DBUS_TYPE_BYTE) \
162 || (type == DBUS_TYPE_BOOLEAN) \
163 || (type == DBUS_TYPE_INT16) \
164 || (type == DBUS_TYPE_UINT16) \
165 || (type == DBUS_TYPE_INT32) \
166 || (type == DBUS_TYPE_UINT32) \
167 || (type == DBUS_TYPE_INT64) \
168 || (type == DBUS_TYPE_UINT64) \
169 || (type == DBUS_TYPE_DOUBLE) \
170 || (type == DBUS_TYPE_STRING) \
171 || (type == DBUS_TYPE_OBJECT_PATH) \
172 || (type == DBUS_TYPE_SIGNATURE))
175 /* This was a macro. On Solaris 2.11 it was said to compile for
176 hours, when optimization is enabled. So we have transferred it into
178 /* Determine the DBusType of a given Lisp symbol. OBJECT must be one
179 of the predefined D-Bus type symbols. */
181 xd_symbol_to_dbus_type (Lisp_Object object
)
184 ((EQ (object
, QCdbus_type_byte
)) ? DBUS_TYPE_BYTE
185 : (EQ (object
, QCdbus_type_boolean
)) ? DBUS_TYPE_BOOLEAN
186 : (EQ (object
, QCdbus_type_int16
)) ? DBUS_TYPE_INT16
187 : (EQ (object
, QCdbus_type_uint16
)) ? DBUS_TYPE_UINT16
188 : (EQ (object
, QCdbus_type_int32
)) ? DBUS_TYPE_INT32
189 : (EQ (object
, QCdbus_type_uint32
)) ? DBUS_TYPE_UINT32
190 : (EQ (object
, QCdbus_type_int64
)) ? DBUS_TYPE_INT64
191 : (EQ (object
, QCdbus_type_uint64
)) ? DBUS_TYPE_UINT64
192 : (EQ (object
, QCdbus_type_double
)) ? DBUS_TYPE_DOUBLE
193 : (EQ (object
, QCdbus_type_string
)) ? DBUS_TYPE_STRING
194 : (EQ (object
, QCdbus_type_object_path
)) ? DBUS_TYPE_OBJECT_PATH
195 : (EQ (object
, QCdbus_type_signature
)) ? DBUS_TYPE_SIGNATURE
196 #ifdef DBUS_TYPE_UNIX_FD
197 : (EQ (object
, QCdbus_type_unix_fd
)) ? DBUS_TYPE_UNIX_FD
199 : (EQ (object
, QCdbus_type_array
)) ? DBUS_TYPE_ARRAY
200 : (EQ (object
, QCdbus_type_variant
)) ? DBUS_TYPE_VARIANT
201 : (EQ (object
, QCdbus_type_struct
)) ? DBUS_TYPE_STRUCT
202 : (EQ (object
, QCdbus_type_dict_entry
)) ? DBUS_TYPE_DICT_ENTRY
203 : DBUS_TYPE_INVALID
);
206 /* Check whether a Lisp symbol is a predefined D-Bus type symbol. */
207 #define XD_DBUS_TYPE_P(object) \
208 (SYMBOLP (object) && ((xd_symbol_to_dbus_type (object) != DBUS_TYPE_INVALID)))
210 /* Determine the DBusType of a given Lisp OBJECT. It is used to
211 convert Lisp objects, being arguments of `dbus-call-method' or
212 `dbus-send-signal', into corresponding C values appended as
213 arguments to a D-Bus message. */
214 #define XD_OBJECT_TO_DBUS_TYPE(object) \
215 ((EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN \
216 : (NATNUMP (object)) ? DBUS_TYPE_UINT32 \
217 : (INTEGERP (object)) ? DBUS_TYPE_INT32 \
218 : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \
219 : (STRINGP (object)) ? DBUS_TYPE_STRING \
220 : (XD_DBUS_TYPE_P (object)) ? xd_symbol_to_dbus_type (object) \
222 ? ((XD_DBUS_TYPE_P (CAR_SAFE (object))) \
223 ? ((XD_BASIC_DBUS_TYPE (xd_symbol_to_dbus_type (CAR_SAFE (object)))) \
225 : xd_symbol_to_dbus_type (CAR_SAFE (object))) \
229 /* Return a list pointer which does not have a Lisp symbol as car. */
230 #define XD_NEXT_VALUE(object) \
231 ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object)
233 /* Transform the message type to its string representation for debug
235 #define XD_MESSAGE_TYPE_TO_STRING(mtype) \
236 ((mtype == DBUS_MESSAGE_TYPE_INVALID) \
237 ? "DBUS_MESSAGE_TYPE_INVALID" \
238 : (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) \
239 ? "DBUS_MESSAGE_TYPE_METHOD_CALL" \
240 : (mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) \
241 ? "DBUS_MESSAGE_TYPE_METHOD_RETURN" \
242 : (mtype == DBUS_MESSAGE_TYPE_ERROR) \
243 ? "DBUS_MESSAGE_TYPE_ERROR" \
244 : "DBUS_MESSAGE_TYPE_SIGNAL")
246 /* Transform the object to its string representation for debug
248 #define XD_OBJECT_TO_STRING(object) \
249 SDATA (format2 ("%s", object, Qnil))
251 /* Check whether X is a valid dbus serial number. If valid, set
252 SERIAL to its value. Otherwise, signal an error. */
253 #define XD_CHECK_DBUS_SERIAL(x, serial) \
255 dbus_uint32_t DBUS_SERIAL_MAX = -1; \
256 if (NATNUMP (x) && XINT (x) <= DBUS_SERIAL_MAX) \
258 else if (MOST_POSITIVE_FIXNUM < DBUS_SERIAL_MAX \
260 && 0 <= XFLOAT_DATA (x) \
261 && XFLOAT_DATA (x) <= DBUS_SERIAL_MAX) \
262 serial = XFLOAT_DATA (x); \
264 XD_SIGNAL2 (build_string ("Invalid dbus serial"), x); \
267 #define XD_DBUS_VALIDATE_BUS_ADDRESS(bus) \
271 DBusAddressEntry **entries; \
274 dbus_error_init (&derror); \
275 if (!dbus_parse_address (SSDATA (bus), &entries, &len, &derror)) \
278 dbus_error_free (&derror); \
279 dbus_address_entries_free (entries); \
284 CHECK_SYMBOL (bus); \
285 if (!(EQ (bus, QCdbus_system_bus) || EQ (bus, QCdbus_session_bus))) \
286 XD_SIGNAL2 (build_string ("Wrong bus name"), bus); \
287 /* We do not want to have an autolaunch for the session bus. */ \
288 if (EQ (bus, QCdbus_session_bus) \
289 && getenv ("DBUS_SESSION_BUS_ADDRESS") == NULL) \
290 XD_SIGNAL2 (build_string ("No connection to bus"), bus); \
294 #define XD_DBUS_VALIDATE_OBJECT(object, func) \
296 if (!NILP (object)) \
299 CHECK_STRING (object); \
300 dbus_error_init (&derror); \
301 if (!func (SSDATA (object), &derror)) \
304 dbus_error_free (&derror); \
308 #if HAVE_DBUS_VALIDATE_BUS_NAME
309 #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \
310 XD_DBUS_VALIDATE_OBJECT(bus_name, dbus_validate_bus_name);
312 #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \
313 if (!NILP (bus_name)) CHECK_STRING (bus_name);
316 #if HAVE_DBUS_VALIDATE_PATH
317 #define XD_DBUS_VALIDATE_PATH(path) \
318 XD_DBUS_VALIDATE_OBJECT(path, dbus_validate_path);
320 #define XD_DBUS_VALIDATE_PATH(path) \
321 if (!NILP (path)) CHECK_STRING (path);
324 #if HAVE_DBUS_VALIDATE_INTERFACE
325 #define XD_DBUS_VALIDATE_INTERFACE(interface) \
326 XD_DBUS_VALIDATE_OBJECT(interface, dbus_validate_interface);
328 #define XD_DBUS_VALIDATE_INTERFACE(interface) \
329 if (!NILP (interface)) CHECK_STRING (interface);
332 #if HAVE_DBUS_VALIDATE_MEMBER
333 #define XD_DBUS_VALIDATE_MEMBER(member) \
334 XD_DBUS_VALIDATE_OBJECT(member, dbus_validate_member);
336 #define XD_DBUS_VALIDATE_MEMBER(member) \
337 if (!NILP (member)) CHECK_STRING (member);
340 /* Append to SIGNATURE a copy of X, making sure SIGNATURE does
341 not become too long. */
343 xd_signature_cat (char *signature
, char const *x
)
345 ptrdiff_t siglen
= strlen (signature
);
346 ptrdiff_t xlen
= strlen (x
);
347 if (DBUS_MAXIMUM_SIGNATURE_LENGTH
- xlen
<= siglen
)
349 strcat (signature
, x
);
352 /* Compute SIGNATURE of OBJECT. It must have a form that it can be
353 used in dbus_message_iter_open_container. DTYPE is the DBusType
354 the object is related to. It is passed as argument, because it
355 cannot be detected in basic type objects, when they are preceded by
356 a type symbol. PARENT_TYPE is the DBusType of a container this
357 signature is embedded, or DBUS_TYPE_INVALID. It is needed for the
358 check that DBUS_TYPE_DICT_ENTRY occurs only as array element. */
360 xd_signature (char *signature
, unsigned int dtype
, unsigned int parent_type
, Lisp_Object object
)
362 unsigned int subtype
;
366 char x
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
373 case DBUS_TYPE_UINT16
:
374 CHECK_NATNUM (object
);
375 sprintf (signature
, "%c", dtype
);
378 case DBUS_TYPE_BOOLEAN
:
379 if (!EQ (object
, Qt
) && !EQ (object
, Qnil
))
380 wrong_type_argument (intern ("booleanp"), object
);
381 sprintf (signature
, "%c", dtype
);
384 case DBUS_TYPE_INT16
:
385 CHECK_NUMBER (object
);
386 sprintf (signature
, "%c", dtype
);
389 case DBUS_TYPE_UINT32
:
390 case DBUS_TYPE_UINT64
:
391 #ifdef DBUS_TYPE_UNIX_FD
392 case DBUS_TYPE_UNIX_FD
:
394 case DBUS_TYPE_INT32
:
395 case DBUS_TYPE_INT64
:
396 case DBUS_TYPE_DOUBLE
:
397 CHECK_NUMBER_OR_FLOAT (object
);
398 sprintf (signature
, "%c", dtype
);
401 case DBUS_TYPE_STRING
:
402 case DBUS_TYPE_OBJECT_PATH
:
403 case DBUS_TYPE_SIGNATURE
:
404 CHECK_STRING (object
);
405 sprintf (signature
, "%c", dtype
);
408 case DBUS_TYPE_ARRAY
:
409 /* Check that all list elements have the same D-Bus type. For
410 complex element types, we just check the container type, not
411 the whole element's signature. */
414 /* Type symbol is optional. */
415 if (EQ (QCdbus_type_array
, CAR_SAFE (elt
)))
416 elt
= XD_NEXT_VALUE (elt
);
418 /* If the array is empty, DBUS_TYPE_STRING is the default
422 subtype
= DBUS_TYPE_STRING
;
423 subsig
= DBUS_TYPE_STRING_AS_STRING
;
427 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
428 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
432 /* If the element type is DBUS_TYPE_SIGNATURE, and this is the
433 only element, the value of this element is used as the
434 array's element signature. */
435 if ((subtype
== DBUS_TYPE_SIGNATURE
)
436 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt
)))
437 && NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
438 subsig
= SSDATA (CAR_SAFE (XD_NEXT_VALUE (elt
)));
442 if (subtype
!= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
)))
443 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (elt
));
444 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
447 subsiglen
= snprintf (signature
, DBUS_MAXIMUM_SIGNATURE_LENGTH
,
448 "%c%s", dtype
, subsig
);
449 if (! (0 <= subsiglen
&& subsiglen
< DBUS_MAXIMUM_SIGNATURE_LENGTH
))
453 case DBUS_TYPE_VARIANT
:
454 /* Check that there is exactly one list element. */
457 elt
= XD_NEXT_VALUE (elt
);
458 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
459 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
461 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
462 wrong_type_argument (intern ("D-Bus"),
463 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt
))));
465 sprintf (signature
, "%c", dtype
);
468 case DBUS_TYPE_STRUCT
:
469 /* A struct list might contain any number of elements with
470 different types. No further check needed. */
473 elt
= XD_NEXT_VALUE (elt
);
475 /* Compose the signature from the elements. It is enclosed by
477 sprintf (signature
, "%c", DBUS_STRUCT_BEGIN_CHAR
);
480 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
481 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
482 xd_signature_cat (signature
, x
);
483 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
485 xd_signature_cat (signature
, DBUS_STRUCT_END_CHAR_AS_STRING
);
488 case DBUS_TYPE_DICT_ENTRY
:
489 /* Check that there are exactly two list elements, and the first
490 one is of basic type. The dictionary entry itself must be an
491 element of an array. */
494 /* Check the parent object type. */
495 if (parent_type
!= DBUS_TYPE_ARRAY
)
496 wrong_type_argument (intern ("D-Bus"), object
);
498 /* Compose the signature from the elements. It is enclosed by
500 sprintf (signature
, "%c", DBUS_DICT_ENTRY_BEGIN_CHAR
);
503 elt
= XD_NEXT_VALUE (elt
);
504 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
505 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
506 xd_signature_cat (signature
, x
);
508 if (!XD_BASIC_DBUS_TYPE (subtype
))
509 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt
)));
511 /* Second element. */
512 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
513 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
514 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
515 xd_signature_cat (signature
, x
);
517 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
518 wrong_type_argument (intern ("D-Bus"),
519 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt
))));
521 /* Closing signature. */
522 xd_signature_cat (signature
, DBUS_DICT_ENTRY_END_CHAR_AS_STRING
);
526 wrong_type_argument (intern ("D-Bus"), object
);
529 XD_DEBUG_MESSAGE ("%s", signature
);
532 /* Append C value, extracted from Lisp OBJECT, to iteration ITER.
533 DTYPE must be a valid DBusType. It is used to convert Lisp
534 objects, being arguments of `dbus-call-method' or
535 `dbus-send-signal', into corresponding C values appended as
536 arguments to a D-Bus message. */
538 xd_append_arg (unsigned int dtype
, Lisp_Object object
, DBusMessageIter
*iter
)
540 char signature
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
541 DBusMessageIter subiter
;
543 if (XD_BASIC_DBUS_TYPE (dtype
))
547 CHECK_NATNUM (object
);
549 unsigned char val
= XFASTINT (object
) & 0xFF;
550 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
551 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
552 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
556 case DBUS_TYPE_BOOLEAN
:
558 dbus_bool_t val
= (NILP (object
)) ? FALSE
: TRUE
;
559 XD_DEBUG_MESSAGE ("%c %s", dtype
, (val
== FALSE
) ? "false" : "true");
560 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
561 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
565 case DBUS_TYPE_INT16
:
566 CHECK_NUMBER (object
);
568 dbus_int16_t val
= XINT (object
);
569 XD_DEBUG_MESSAGE ("%c %d", dtype
, (int) val
);
570 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
571 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
575 case DBUS_TYPE_UINT16
:
576 CHECK_NATNUM (object
);
578 dbus_uint16_t val
= XFASTINT (object
);
579 XD_DEBUG_MESSAGE ("%c %u", dtype
, (unsigned int) val
);
580 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
581 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
585 case DBUS_TYPE_INT32
:
587 dbus_int32_t val
= extract_float (object
);
588 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
589 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
590 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
594 case DBUS_TYPE_UINT32
:
595 #ifdef DBUS_TYPE_UNIX_FD
596 case DBUS_TYPE_UNIX_FD
:
599 dbus_uint32_t val
= extract_float (object
);
600 XD_DEBUG_MESSAGE ("%c %u", dtype
, val
);
601 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
602 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
606 case DBUS_TYPE_INT64
:
608 dbus_int64_t val
= extract_float (object
);
609 XD_DEBUG_MESSAGE ("%c %d", dtype
, (int) val
);
610 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
611 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
615 case DBUS_TYPE_UINT64
:
617 dbus_uint64_t val
= extract_float (object
);
618 XD_DEBUG_MESSAGE ("%c %"pI
"d", dtype
, val
);
619 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
620 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
624 case DBUS_TYPE_DOUBLE
:
626 double val
= extract_float (object
);
627 XD_DEBUG_MESSAGE ("%c %f", dtype
, val
);
628 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
629 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
633 case DBUS_TYPE_STRING
:
634 case DBUS_TYPE_OBJECT_PATH
:
635 case DBUS_TYPE_SIGNATURE
:
636 CHECK_STRING (object
);
638 /* We need to send a valid UTF-8 string. We could encode `object'
639 but by not encoding it, we guarantee it's valid utf-8, even if
640 it contains eight-bit-bytes. Of course, you can still send
641 manually-crafted junk by passing a unibyte string. */
642 char *val
= SSDATA (object
);
643 XD_DEBUG_MESSAGE ("%c %s", dtype
, val
);
644 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
645 XD_SIGNAL2 (build_string ("Unable to append argument"), object
);
650 else /* Compound types. */
653 /* All compound types except array have a type symbol. For
654 array, it is optional. Skip it. */
655 if (!XD_BASIC_DBUS_TYPE (XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
))))
656 object
= XD_NEXT_VALUE (object
);
658 /* Open new subiteration. */
661 case DBUS_TYPE_ARRAY
:
662 /* An array has only elements of the same type. So it is
663 sufficient to check the first element's signature
667 /* If the array is empty, DBUS_TYPE_STRING is the default
669 strcpy (signature
, DBUS_TYPE_STRING_AS_STRING
);
672 /* If the element type is DBUS_TYPE_SIGNATURE, and this is
673 the only element, the value of this element is used as
674 the array's element signature. */
675 if ((XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
))
676 == DBUS_TYPE_SIGNATURE
)
677 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object
)))
678 && NILP (CDR_SAFE (XD_NEXT_VALUE (object
))))
680 strcpy (signature
, SSDATA (CAR_SAFE (XD_NEXT_VALUE (object
))));
681 object
= CDR_SAFE (XD_NEXT_VALUE (object
));
685 xd_signature (signature
,
686 XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
)),
687 dtype
, CAR_SAFE (XD_NEXT_VALUE (object
)));
689 XD_DEBUG_MESSAGE ("%c %s %s", dtype
, signature
,
690 XD_OBJECT_TO_STRING (object
));
691 if (!dbus_message_iter_open_container (iter
, dtype
,
692 signature
, &subiter
))
693 XD_SIGNAL3 (build_string ("Cannot open container"),
694 make_number (dtype
), build_string (signature
));
697 case DBUS_TYPE_VARIANT
:
698 /* A variant has just one element. */
699 xd_signature (signature
, XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
)),
700 dtype
, CAR_SAFE (XD_NEXT_VALUE (object
)));
702 XD_DEBUG_MESSAGE ("%c %s %s", dtype
, signature
,
703 XD_OBJECT_TO_STRING (object
));
704 if (!dbus_message_iter_open_container (iter
, dtype
,
705 signature
, &subiter
))
706 XD_SIGNAL3 (build_string ("Cannot open container"),
707 make_number (dtype
), build_string (signature
));
710 case DBUS_TYPE_STRUCT
:
711 case DBUS_TYPE_DICT_ENTRY
:
712 /* These containers do not require a signature. */
713 XD_DEBUG_MESSAGE ("%c %s", dtype
, XD_OBJECT_TO_STRING (object
));
714 if (!dbus_message_iter_open_container (iter
, dtype
, NULL
, &subiter
))
715 XD_SIGNAL2 (build_string ("Cannot open container"),
716 make_number (dtype
));
720 /* Loop over list elements. */
721 while (!NILP (object
))
723 dtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
));
724 object
= XD_NEXT_VALUE (object
);
726 xd_append_arg (dtype
, CAR_SAFE (object
), &subiter
);
728 object
= CDR_SAFE (object
);
731 /* Close the subiteration. */
732 if (!dbus_message_iter_close_container (iter
, &subiter
))
733 XD_SIGNAL2 (build_string ("Cannot close container"),
734 make_number (dtype
));
738 /* Retrieve C value from a DBusMessageIter structure ITER, and return
739 a converted Lisp object. The type DTYPE of the argument of the
740 D-Bus message must be a valid DBusType. Compound D-Bus types
741 result always in a Lisp list. */
743 xd_retrieve_arg (unsigned int dtype
, DBusMessageIter
*iter
)
751 dbus_message_iter_get_basic (iter
, &val
);
753 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
754 return make_number (val
);
757 case DBUS_TYPE_BOOLEAN
:
760 dbus_message_iter_get_basic (iter
, &val
);
761 XD_DEBUG_MESSAGE ("%c %s", dtype
, (val
== FALSE
) ? "false" : "true");
762 return (val
== FALSE
) ? Qnil
: Qt
;
765 case DBUS_TYPE_INT16
:
768 dbus_message_iter_get_basic (iter
, &val
);
769 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
770 return make_number (val
);
773 case DBUS_TYPE_UINT16
:
776 dbus_message_iter_get_basic (iter
, &val
);
777 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
778 return make_number (val
);
781 case DBUS_TYPE_INT32
:
784 dbus_message_iter_get_basic (iter
, &val
);
785 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
786 return make_fixnum_or_float (val
);
789 case DBUS_TYPE_UINT32
:
790 #ifdef DBUS_TYPE_UNIX_FD
791 case DBUS_TYPE_UNIX_FD
:
795 dbus_message_iter_get_basic (iter
, &val
);
796 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
797 return make_fixnum_or_float (val
);
800 case DBUS_TYPE_INT64
:
803 dbus_message_iter_get_basic (iter
, &val
);
804 XD_DEBUG_MESSAGE ("%c %d", dtype
, (int) val
);
805 return make_fixnum_or_float (val
);
808 case DBUS_TYPE_UINT64
:
811 dbus_message_iter_get_basic (iter
, &val
);
812 XD_DEBUG_MESSAGE ("%c %d", dtype
, (int) val
);
813 return make_fixnum_or_float (val
);
816 case DBUS_TYPE_DOUBLE
:
819 dbus_message_iter_get_basic (iter
, &val
);
820 XD_DEBUG_MESSAGE ("%c %f", dtype
, val
);
821 return make_float (val
);
824 case DBUS_TYPE_STRING
:
825 case DBUS_TYPE_OBJECT_PATH
:
826 case DBUS_TYPE_SIGNATURE
:
829 dbus_message_iter_get_basic (iter
, &val
);
830 XD_DEBUG_MESSAGE ("%c %s", dtype
, val
);
831 return build_string (val
);
834 case DBUS_TYPE_ARRAY
:
835 case DBUS_TYPE_VARIANT
:
836 case DBUS_TYPE_STRUCT
:
837 case DBUS_TYPE_DICT_ENTRY
:
841 DBusMessageIter subiter
;
845 dbus_message_iter_recurse (iter
, &subiter
);
846 while ((subtype
= dbus_message_iter_get_arg_type (&subiter
))
847 != DBUS_TYPE_INVALID
)
849 result
= Fcons (xd_retrieve_arg (subtype
, &subiter
), result
);
850 dbus_message_iter_next (&subiter
);
852 XD_DEBUG_MESSAGE ("%c %s", dtype
, XD_OBJECT_TO_STRING (result
));
853 RETURN_UNGCPRO (Fnreverse (result
));
857 XD_DEBUG_MESSAGE ("DBusType '%c' not supported", dtype
);
862 /* Return the number of references of the shared CONNECTION. */
864 xd_get_connection_references (DBusConnection
*connection
)
868 /* We cannot access the DBusConnection structure, it is not public.
869 But we know, that the reference counter is the first field in
871 refcount
= (void *) &connection
;
872 refcount
= (void *) *refcount
;
876 /* Return D-Bus connection address. BUS is either a Lisp symbol,
877 :system or :session, or a string denoting the bus address. */
878 static DBusConnection
*
879 xd_get_connection_address (Lisp_Object bus
)
881 DBusConnection
*connection
;
884 val
= CDR_SAFE (Fassoc (bus
, Vdbus_registered_buses
));
886 XD_SIGNAL2 (build_string ("No connection to bus"), bus
);
888 connection
= (DBusConnection
*) XFASTINT (val
);
890 if (!dbus_connection_get_is_connected (connection
))
891 XD_SIGNAL2 (build_string ("No connection to bus"), bus
);
896 /* Return the file descriptor for WATCH, -1 if not found. */
898 xd_find_watch_fd (DBusWatch
*watch
)
900 #if HAVE_DBUS_WATCH_GET_UNIX_FD
901 /* TODO: Reverse these on Win32, which prefers the opposite. */
902 int fd
= dbus_watch_get_unix_fd (watch
);
904 fd
= dbus_watch_get_socket (watch
);
906 int fd
= dbus_watch_get_fd (watch
);
913 xd_read_queued_messages (int fd
, void *data
, int for_read
);
915 /* Start monitoring WATCH for possible I/O. */
917 xd_add_watch (DBusWatch
*watch
, void *data
)
919 unsigned int flags
= dbus_watch_get_flags (watch
);
920 int fd
= xd_find_watch_fd (watch
);
922 XD_DEBUG_MESSAGE ("fd %d, write %d, enabled %d",
923 fd
, flags
& DBUS_WATCH_WRITABLE
,
924 dbus_watch_get_enabled (watch
));
929 if (dbus_watch_get_enabled (watch
))
931 if (flags
& DBUS_WATCH_WRITABLE
)
932 add_write_fd (fd
, xd_read_queued_messages
, data
);
933 if (flags
& DBUS_WATCH_READABLE
)
934 add_read_fd (fd
, xd_read_queued_messages
, data
);
939 /* Stop monitoring WATCH for possible I/O.
940 DATA is the used bus, either a string or QCdbus_system_bus or
941 QCdbus_session_bus. */
943 xd_remove_watch (DBusWatch
*watch
, void *data
)
945 unsigned int flags
= dbus_watch_get_flags (watch
);
946 int fd
= xd_find_watch_fd (watch
);
948 XD_DEBUG_MESSAGE ("fd %d", fd
);
953 /* Unset session environment. */
954 if (XSYMBOL (QCdbus_session_bus
) == data
)
956 // XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
957 // unsetenv ("DBUS_SESSION_BUS_ADDRESS");
960 if (flags
& DBUS_WATCH_WRITABLE
)
961 delete_write_fd (fd
);
962 if (flags
& DBUS_WATCH_READABLE
)
966 /* Toggle monitoring WATCH for possible I/O. */
968 xd_toggle_watch (DBusWatch
*watch
, void *data
)
970 if (dbus_watch_get_enabled (watch
))
971 xd_add_watch (watch
, data
);
973 xd_remove_watch (watch
, data
);
976 /* Close connection to D-Bus BUS. */
978 xd_close_bus (Lisp_Object bus
)
980 DBusConnection
*connection
;
983 /* Check whether we are connected. */
984 val
= Fassoc (bus
, Vdbus_registered_buses
);
988 /* Retrieve bus address. */
989 connection
= xd_get_connection_address (bus
);
991 /* Close connection, if there isn't another shared application. */
992 if (xd_get_connection_references (connection
) == 1)
994 XD_DEBUG_MESSAGE ("Close connection to bus %s",
995 XD_OBJECT_TO_STRING (bus
));
996 dbus_connection_close (connection
);
999 /* Decrement reference count. */
1000 dbus_connection_unref (connection
);
1002 /* Remove bus from list of registered buses. */
1003 Vdbus_registered_buses
= Fdelete (val
, Vdbus_registered_buses
);
1009 DEFUN ("dbus-init-bus", Fdbus_init_bus
, Sdbus_init_bus
, 1, 2, 0,
1010 doc
: /* Establish the connection to D-Bus BUS.
1012 BUS can be either the symbol `:system' or the symbol `:session', or it
1013 can be a string denoting the address of the corresponding bus. For
1014 the system and session buses, this function is called when loading
1015 `dbus.el', there is no need to call it again.
1017 The function returns a number, which counts the connections this Emacs
1018 session has established to the BUS under the same unique name (see
1019 `dbus-get-unique-name'). It depends on the libraries Emacs is linked
1020 with, and on the environment Emacs is running. For example, if Emacs
1021 is linked with the gtk toolkit, and it runs in a GTK-aware environment
1022 like Gnome, another connection might already be established.
1024 When PRIVATE is non-nil, a new connection is established instead of
1025 reusing an existing one. It results in a new unique name at the bus.
1026 This can be used, if it is necessary to distinguish from another
1027 connection used in the same Emacs process, like the one established by
1028 GTK+. It should be used with care for at least the `:system' and
1029 `:session' buses, because other Emacs Lisp packages might already use
1030 this connection to those buses. */)
1031 (Lisp_Object bus
, Lisp_Object
private)
1033 DBusConnection
*connection
;
1038 /* Check parameter. */
1039 XD_DBUS_VALIDATE_BUS_ADDRESS (bus
);
1041 /* Close bus if it is already open. */
1045 dbus_error_init (&derror
);
1047 /* Open the connection. */
1050 connection
= dbus_connection_open (SSDATA (bus
), &derror
);
1052 connection
= dbus_connection_open_private (SSDATA (bus
), &derror
);
1056 connection
= dbus_bus_get (EQ (bus
, QCdbus_system_bus
)
1057 ? DBUS_BUS_SYSTEM
: DBUS_BUS_SESSION
,
1060 connection
= dbus_bus_get_private (EQ (bus
, QCdbus_system_bus
)
1061 ? DBUS_BUS_SYSTEM
: DBUS_BUS_SESSION
,
1064 if (dbus_error_is_set (&derror
))
1067 if (connection
== NULL
)
1068 XD_SIGNAL2 (build_string ("No connection to bus"), bus
);
1070 /* If it is not the system or session bus, we must register
1071 ourselves. Otherwise, we have called dbus_bus_get, which has
1072 configured us to exit if the connection closes - we undo this
1075 dbus_bus_register (connection
, &derror
);
1077 dbus_connection_set_exit_on_disconnect (connection
, FALSE
);
1079 if (dbus_error_is_set (&derror
))
1082 /* Add the watch functions. We pass also the bus as data, in order
1083 to distinguish between the buses in xd_remove_watch. */
1084 if (!dbus_connection_set_watch_functions (connection
,
1089 ? (void *) XSYMBOL (bus
)
1090 : (void *) XSTRING (bus
),
1092 XD_SIGNAL1 (build_string ("Cannot add watch functions"));
1094 /* Add bus to list of registered buses. */
1095 XSETFASTINT (val
, connection
);
1096 Vdbus_registered_buses
= Fcons (Fcons (bus
, val
), Vdbus_registered_buses
);
1098 /* We do not want to abort. */
1099 putenv ((char *) "DBUS_FATAL_WARNINGS=0");
1102 dbus_error_free (&derror
);
1104 /* Return reference counter. */
1105 refcount
= xd_get_connection_references (connection
);
1106 XD_DEBUG_MESSAGE ("Bus %s, Reference counter %d",
1107 XD_OBJECT_TO_STRING (bus
), refcount
);
1108 return make_number (refcount
);
1111 DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name
, Sdbus_get_unique_name
,
1113 doc
: /* Return the unique name of Emacs registered at D-Bus BUS. */)
1116 DBusConnection
*connection
;
1119 /* Check parameter. */
1120 XD_DBUS_VALIDATE_BUS_ADDRESS (bus
);
1122 /* Retrieve bus address. */
1123 connection
= xd_get_connection_address (bus
);
1125 /* Request the name. */
1126 name
= dbus_bus_get_unique_name (connection
);
1128 XD_SIGNAL1 (build_string ("No unique name available"));
1131 return build_string (name
);
1134 DEFUN ("dbus-message-internal", Fdbus_message_internal
, Sdbus_message_internal
,
1136 doc
: /* Send a D-Bus message.
1137 This is an internal function, it shall not be used outside dbus.el.
1139 The following usages are expected:
1141 `dbus-call-method', `dbus-call-method-asynchronously':
1142 \(dbus-message-internal
1143 dbus-message-type-method-call BUS SERVICE PATH INTERFACE METHOD HANDLER
1144 &optional :timeout TIMEOUT &rest ARGS)
1147 \(dbus-message-internal
1148 dbus-message-type-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS)
1150 `dbus-method-return-internal':
1151 \(dbus-message-internal
1152 dbus-message-type-method-return BUS SERVICE SERIAL &rest ARGS)
1154 `dbus-method-error-internal':
1155 \(dbus-message-internal
1156 dbus-message-type-error BUS SERVICE SERIAL &rest ARGS)
1158 usage: (dbus-message-internal &rest REST) */)
1159 (ptrdiff_t nargs
, Lisp_Object
*args
)
1161 Lisp_Object message_type
, bus
, service
, handler
;
1162 Lisp_Object path
= Qnil
;
1163 Lisp_Object interface
= Qnil
;
1164 Lisp_Object member
= Qnil
;
1166 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
, gcpro6
;
1167 DBusConnection
*connection
;
1168 DBusMessage
*dmessage
;
1169 DBusMessageIter iter
;
1172 dbus_uint32_t serial
= 0;
1175 char signature
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
1177 /* Initialize parameters. */
1178 message_type
= args
[0];
1183 CHECK_NATNUM (message_type
);
1184 mtype
= XFASTINT (message_type
);
1185 if ((mtype
<= DBUS_MESSAGE_TYPE_INVALID
) || (mtype
>= DBUS_NUM_MESSAGE_TYPES
))
1186 XD_SIGNAL2 (build_string ("Invalid message type"), message_type
);
1188 if ((mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1189 || (mtype
== DBUS_MESSAGE_TYPE_SIGNAL
))
1192 interface
= args
[4];
1194 if (mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1196 count
= (mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
) ? 7 : 6;
1198 else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1200 XD_CHECK_DBUS_SERIAL (args
[3], serial
);
1204 /* Check parameters. */
1205 XD_DBUS_VALIDATE_BUS_ADDRESS (bus
);
1206 XD_DBUS_VALIDATE_BUS_NAME (service
);
1208 xsignal2 (Qwrong_number_of_arguments
,
1209 Qdbus_message_internal
,
1210 make_number (nargs
));
1212 if ((mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1213 || (mtype
== DBUS_MESSAGE_TYPE_SIGNAL
))
1215 XD_DBUS_VALIDATE_PATH (path
);
1216 XD_DBUS_VALIDATE_INTERFACE (interface
);
1217 XD_DBUS_VALIDATE_MEMBER (member
);
1218 if (!NILP (handler
) && (!FUNCTIONP (handler
)))
1219 wrong_type_argument (Qinvalid_function
, handler
);
1222 /* Protect Lisp variables. */
1223 GCPRO6 (bus
, service
, path
, interface
, member
, handler
);
1225 /* Trace parameters. */
1228 case DBUS_MESSAGE_TYPE_METHOD_CALL
:
1229 XD_DEBUG_MESSAGE ("%s %s %s %s %s %s %s",
1230 XD_MESSAGE_TYPE_TO_STRING (mtype
),
1231 XD_OBJECT_TO_STRING (bus
),
1232 XD_OBJECT_TO_STRING (service
),
1233 XD_OBJECT_TO_STRING (path
),
1234 XD_OBJECT_TO_STRING (interface
),
1235 XD_OBJECT_TO_STRING (member
),
1236 XD_OBJECT_TO_STRING (handler
));
1238 case DBUS_MESSAGE_TYPE_SIGNAL
:
1239 XD_DEBUG_MESSAGE ("%s %s %s %s %s %s",
1240 XD_MESSAGE_TYPE_TO_STRING (mtype
),
1241 XD_OBJECT_TO_STRING (bus
),
1242 XD_OBJECT_TO_STRING (service
),
1243 XD_OBJECT_TO_STRING (path
),
1244 XD_OBJECT_TO_STRING (interface
),
1245 XD_OBJECT_TO_STRING (member
));
1247 default: /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1248 XD_DEBUG_MESSAGE ("%s %s %s %u",
1249 XD_MESSAGE_TYPE_TO_STRING (mtype
),
1250 XD_OBJECT_TO_STRING (bus
),
1251 XD_OBJECT_TO_STRING (service
),
1255 /* Retrieve bus address. */
1256 connection
= xd_get_connection_address (bus
);
1258 /* Create the D-Bus message. */
1259 dmessage
= dbus_message_new (mtype
);
1260 if (dmessage
== NULL
)
1263 XD_SIGNAL1 (build_string ("Unable to create a new message"));
1266 if (STRINGP (service
))
1268 if (mtype
!= DBUS_MESSAGE_TYPE_SIGNAL
)
1269 /* Set destination. */
1271 if (!dbus_message_set_destination (dmessage
, SSDATA (service
)))
1274 XD_SIGNAL2 (build_string ("Unable to set the destination"),
1280 /* Set destination for unicast signals. */
1284 /* If it is the same unique name as we are registered at the
1285 bus or an unknown name, we regard it as broadcast message
1286 due to backward compatibility. */
1287 if (dbus_bus_name_has_owner (connection
, SSDATA (service
), NULL
))
1288 uname
= call2 (intern ("dbus-get-name-owner"), bus
, service
);
1293 && (strcmp (dbus_bus_get_unique_name (connection
), SSDATA (uname
))
1295 && (!dbus_message_set_destination (dmessage
, SSDATA (service
))))
1298 XD_SIGNAL2 (build_string ("Unable to set signal destination"),
1304 /* Set message parameters. */
1305 if ((mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1306 || (mtype
== DBUS_MESSAGE_TYPE_SIGNAL
))
1308 if ((!dbus_message_set_path (dmessage
, SSDATA (path
)))
1309 || (!dbus_message_set_interface (dmessage
, SSDATA (interface
)))
1310 || (!dbus_message_set_member (dmessage
, SSDATA (member
))))
1313 XD_SIGNAL1 (build_string ("Unable to set the message parameter"));
1317 else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1319 if (!dbus_message_set_reply_serial (dmessage
, serial
))
1322 XD_SIGNAL1 (build_string ("Unable to create a return message"));
1325 if ((mtype
== DBUS_MESSAGE_TYPE_ERROR
)
1326 && (!dbus_message_set_error_name (dmessage
, DBUS_ERROR_FAILED
)))
1329 XD_SIGNAL1 (build_string ("Unable to create a error message"));
1333 /* Check for timeout parameter. */
1334 if ((count
+2 <= nargs
) && (EQ ((args
[count
]), QCdbus_timeout
)))
1336 CHECK_NATNUM (args
[count
+1]);
1337 timeout
= XFASTINT (args
[count
+1]);
1341 /* Initialize parameter list of message. */
1342 dbus_message_iter_init_append (dmessage
, &iter
);
1344 /* Append parameters to the message. */
1345 for (; count
< nargs
; ++count
)
1347 dtype
= XD_OBJECT_TO_DBUS_TYPE (args
[count
]);
1348 if (XD_DBUS_TYPE_P (args
[count
]))
1350 XD_DEBUG_VALID_LISP_OBJECT_P (args
[count
]);
1351 XD_DEBUG_VALID_LISP_OBJECT_P (args
[count
+1]);
1352 XD_DEBUG_MESSAGE ("Parameter%"pD
"d %s %s", count
- 4,
1353 XD_OBJECT_TO_STRING (args
[count
]),
1354 XD_OBJECT_TO_STRING (args
[count
+1]));
1359 XD_DEBUG_VALID_LISP_OBJECT_P (args
[count
]);
1360 XD_DEBUG_MESSAGE ("Parameter%"pD
"d %s", count
- 4,
1361 XD_OBJECT_TO_STRING (args
[count
]));
1364 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1365 indication that there is no parent type. */
1366 xd_signature (signature
, dtype
, DBUS_TYPE_INVALID
, args
[count
]);
1368 xd_append_arg (dtype
, args
[count
], &iter
);
1371 if (!NILP (handler
))
1373 /* Send the message. The message is just added to the outgoing
1375 if (!dbus_connection_send_with_reply (connection
, dmessage
,
1379 XD_SIGNAL1 (build_string ("Cannot send message"));
1382 /* The result is the key in Vdbus_registered_objects_table. */
1383 serial
= dbus_message_get_serial (dmessage
);
1384 result
= list3 (QCdbus_registered_serial
,
1385 bus
, make_fixnum_or_float (serial
));
1387 /* Create a hash table entry. */
1388 Fputhash (result
, handler
, Vdbus_registered_objects_table
);
1392 /* Send the message. The message is just added to the outgoing
1394 if (!dbus_connection_send (connection
, dmessage
, NULL
))
1397 XD_SIGNAL1 (build_string ("Cannot send message"));
1403 XD_DEBUG_MESSAGE ("Message sent: %s", XD_OBJECT_TO_STRING (result
));
1406 dbus_message_unref (dmessage
);
1408 /* Return the result. */
1409 RETURN_UNGCPRO (result
);
1412 /* Read one queued incoming message of the D-Bus BUS.
1413 BUS is either a Lisp symbol, :system or :session, or a string denoting
1416 xd_read_message_1 (DBusConnection
*connection
, Lisp_Object bus
)
1418 Lisp_Object args
, key
, value
;
1419 struct gcpro gcpro1
;
1420 struct input_event event
;
1421 DBusMessage
*dmessage
;
1422 DBusMessageIter iter
;
1425 dbus_uint32_t serial
;
1426 unsigned int ui_serial
;
1427 const char *uname
, *path
, *interface
, *member
;
1429 dmessage
= dbus_connection_pop_message (connection
);
1431 /* Return if there is no queued message. */
1432 if (dmessage
== NULL
)
1435 /* Collect the parameters. */
1439 /* Loop over the resulting parameters. Construct a list. */
1440 if (dbus_message_iter_init (dmessage
, &iter
))
1442 while ((dtype
= dbus_message_iter_get_arg_type (&iter
))
1443 != DBUS_TYPE_INVALID
)
1445 args
= Fcons (xd_retrieve_arg (dtype
, &iter
), args
);
1446 dbus_message_iter_next (&iter
);
1448 /* The arguments are stored in reverse order. Reorder them. */
1449 args
= Fnreverse (args
);
1452 /* Read message type, message serial, unique name, object path,
1453 interface and member from the message. */
1454 mtype
= dbus_message_get_type (dmessage
);
1455 ui_serial
= serial
=
1456 ((mtype
== DBUS_MESSAGE_TYPE_METHOD_RETURN
)
1457 || (mtype
== DBUS_MESSAGE_TYPE_ERROR
))
1458 ? dbus_message_get_reply_serial (dmessage
)
1459 : dbus_message_get_serial (dmessage
);
1460 uname
= dbus_message_get_sender (dmessage
);
1461 path
= dbus_message_get_path (dmessage
);
1462 interface
= dbus_message_get_interface (dmessage
);
1463 member
= dbus_message_get_member (dmessage
);
1465 XD_DEBUG_MESSAGE ("Event received: %s %u %s %s %s %s %s",
1466 XD_MESSAGE_TYPE_TO_STRING (mtype
),
1467 ui_serial
, uname
, path
, interface
, member
,
1468 XD_OBJECT_TO_STRING (args
));
1470 if (mtype
== DBUS_MESSAGE_TYPE_INVALID
)
1473 else if ((mtype
== DBUS_MESSAGE_TYPE_METHOD_RETURN
)
1474 || (mtype
== DBUS_MESSAGE_TYPE_ERROR
))
1476 /* Search for a registered function of the message. */
1477 key
= list3 (QCdbus_registered_serial
, bus
,
1478 make_fixnum_or_float (serial
));
1479 value
= Fgethash (key
, Vdbus_registered_objects_table
, Qnil
);
1481 /* There shall be exactly one entry. Construct an event. */
1485 /* Remove the entry. */
1486 Fremhash (key
, Vdbus_registered_objects_table
);
1488 /* Construct an event. */
1490 event
.kind
= DBUS_EVENT
;
1491 event
.frame_or_window
= Qnil
;
1492 event
.arg
= Fcons (value
, args
);
1495 else /* DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_SIGNAL. */
1497 /* Vdbus_registered_objects_table requires non-nil interface and
1499 if ((interface
== NULL
) || (member
== NULL
))
1502 /* Search for a registered function of the message. */
1503 key
= list4 ((mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
)
1504 ? QCdbus_registered_method
1505 : QCdbus_registered_signal
,
1506 bus
, build_string (interface
), build_string (member
));
1507 value
= Fgethash (key
, Vdbus_registered_objects_table
, Qnil
);
1509 /* Loop over the registered functions. Construct an event. */
1510 while (!NILP (value
))
1512 key
= CAR_SAFE (value
);
1513 /* key has the structure (UNAME SERVICE PATH HANDLER). */
1514 if (((uname
== NULL
)
1515 || (NILP (CAR_SAFE (key
)))
1516 || (strcmp (uname
, SSDATA (CAR_SAFE (key
))) == 0))
1518 || (NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))
1520 SSDATA (CAR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))
1522 && (!NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))))
1525 event
.kind
= DBUS_EVENT
;
1526 event
.frame_or_window
= Qnil
;
1528 = Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key
)))), args
);
1531 value
= CDR_SAFE (value
);
1538 /* Add type, serial, uname, path, interface and member to the event. */
1539 event
.arg
= Fcons ((member
== NULL
? Qnil
: build_string (member
)),
1541 event
.arg
= Fcons ((interface
== NULL
? Qnil
: build_string (interface
)),
1543 event
.arg
= Fcons ((path
== NULL
? Qnil
: build_string (path
)),
1545 event
.arg
= Fcons ((uname
== NULL
? Qnil
: build_string (uname
)),
1547 event
.arg
= Fcons (make_fixnum_or_float (serial
), event
.arg
);
1548 event
.arg
= Fcons (make_number (mtype
), event
.arg
);
1550 /* Add the bus symbol to the event. */
1551 event
.arg
= Fcons (bus
, event
.arg
);
1553 /* Store it into the input event queue. */
1554 kbd_buffer_store_event (&event
);
1556 XD_DEBUG_MESSAGE ("Event stored: %s", XD_OBJECT_TO_STRING (event
.arg
));
1560 dbus_message_unref (dmessage
);
1565 /* Read queued incoming messages of the D-Bus BUS.
1566 BUS is either a Lisp symbol, :system or :session, or a string denoting
1569 xd_read_message (Lisp_Object bus
)
1571 /* Retrieve bus address. */
1572 DBusConnection
*connection
= xd_get_connection_address (bus
);
1574 /* Non blocking read of the next available message. */
1575 dbus_connection_read_write (connection
, 0);
1577 while (dbus_connection_get_dispatch_status (connection
)
1578 != DBUS_DISPATCH_COMPLETE
)
1579 xd_read_message_1 (connection
, bus
);
1583 /* Callback called when something is ready to read or write. */
1585 xd_read_queued_messages (int fd
, void *data
, int for_read
)
1587 Lisp_Object busp
= Vdbus_registered_buses
;
1588 Lisp_Object bus
= Qnil
;
1591 /* Find bus related to fd. */
1593 while (!NILP (busp
))
1595 key
= CAR_SAFE (CAR_SAFE (busp
));
1596 if ((SYMBOLP (key
) && XSYMBOL (key
) == data
)
1597 || (STRINGP (key
) && XSTRING (key
) == data
))
1599 busp
= CDR_SAFE (busp
);
1605 /* We ignore all Lisp errors during the call. */
1606 xd_in_read_queued_messages
= 1;
1607 internal_catch (Qdbus_error
, xd_read_message
, bus
);
1608 xd_in_read_queued_messages
= 0;
1613 syms_of_dbusbind (void)
1616 DEFSYM (Qdbus_init_bus
, "dbus-init-bus");
1617 defsubr (&Sdbus_init_bus
);
1619 DEFSYM (Qdbus_get_unique_name
, "dbus-get-unique-name");
1620 defsubr (&Sdbus_get_unique_name
);
1622 DEFSYM (Qdbus_message_internal
, "dbus-message-internal");
1623 defsubr (&Sdbus_message_internal
);
1625 DEFSYM (Qdbus_error
, "dbus-error");
1626 Fput (Qdbus_error
, Qerror_conditions
,
1627 list2 (Qdbus_error
, Qerror
));
1628 Fput (Qdbus_error
, Qerror_message
,
1629 make_pure_c_string ("D-Bus error"));
1631 DEFSYM (QCdbus_system_bus
, ":system");
1632 DEFSYM (QCdbus_session_bus
, ":session");
1633 DEFSYM (QCdbus_timeout
, ":timeout");
1634 DEFSYM (QCdbus_type_byte
, ":byte");
1635 DEFSYM (QCdbus_type_boolean
, ":boolean");
1636 DEFSYM (QCdbus_type_int16
, ":int16");
1637 DEFSYM (QCdbus_type_uint16
, ":uint16");
1638 DEFSYM (QCdbus_type_int32
, ":int32");
1639 DEFSYM (QCdbus_type_uint32
, ":uint32");
1640 DEFSYM (QCdbus_type_int64
, ":int64");
1641 DEFSYM (QCdbus_type_uint64
, ":uint64");
1642 DEFSYM (QCdbus_type_double
, ":double");
1643 DEFSYM (QCdbus_type_string
, ":string");
1644 DEFSYM (QCdbus_type_object_path
, ":object-path");
1645 DEFSYM (QCdbus_type_signature
, ":signature");
1646 #ifdef DBUS_TYPE_UNIX_FD
1647 DEFSYM (QCdbus_type_unix_fd
, ":unix-fd");
1649 DEFSYM (QCdbus_type_array
, ":array");
1650 DEFSYM (QCdbus_type_variant
, ":variant");
1651 DEFSYM (QCdbus_type_struct
, ":struct");
1652 DEFSYM (QCdbus_type_dict_entry
, ":dict-entry");
1653 DEFSYM (QCdbus_registered_serial
, ":serial");
1654 DEFSYM (QCdbus_registered_method
, ":method");
1655 DEFSYM (QCdbus_registered_signal
, ":signal");
1657 DEFVAR_LISP ("dbus-compiled-version",
1658 Vdbus_compiled_version
,
1659 doc
: /* The version of D-Bus Emacs is compiled against. */);
1660 #ifdef DBUS_VERSION_STRING
1661 Vdbus_compiled_version
= make_pure_c_string (DBUS_VERSION_STRING
);
1663 Vdbus_compiled_version
= Qnil
;
1666 DEFVAR_LISP ("dbus-runtime-version",
1667 Vdbus_runtime_version
,
1668 doc
: /* The version of D-Bus Emacs runs with. */);
1671 int major
, minor
, micro
;
1673 dbus_get_version (&major
, &minor
, µ
);
1674 snprintf (s
, sizeof s
, "%d.%d.%d", major
, minor
, micro
);
1675 Vdbus_runtime_version
= make_string (s
, strlen (s
));
1677 Vdbus_runtime_version
= Qnil
;
1681 DEFVAR_LISP ("dbus-message-type-invalid",
1682 Vdbus_message_type_invalid
,
1683 doc
: /* This value is never a valid message type. */);
1684 Vdbus_message_type_invalid
= make_number (DBUS_MESSAGE_TYPE_INVALID
);
1686 DEFVAR_LISP ("dbus-message-type-method-call",
1687 Vdbus_message_type_method_call
,
1688 doc
: /* Message type of a method call message. */);
1689 Vdbus_message_type_method_call
= make_number (DBUS_MESSAGE_TYPE_METHOD_CALL
);
1691 DEFVAR_LISP ("dbus-message-type-method-return",
1692 Vdbus_message_type_method_return
,
1693 doc
: /* Message type of a method return message. */);
1694 Vdbus_message_type_method_return
1695 = make_number (DBUS_MESSAGE_TYPE_METHOD_RETURN
);
1697 DEFVAR_LISP ("dbus-message-type-error",
1698 Vdbus_message_type_error
,
1699 doc
: /* Message type of an error reply message. */);
1700 Vdbus_message_type_error
= make_number (DBUS_MESSAGE_TYPE_ERROR
);
1702 DEFVAR_LISP ("dbus-message-type-signal",
1703 Vdbus_message_type_signal
,
1704 doc
: /* Message type of a signal message. */);
1705 Vdbus_message_type_signal
= make_number (DBUS_MESSAGE_TYPE_SIGNAL
);
1707 DEFVAR_LISP ("dbus-registered-buses",
1708 Vdbus_registered_buses
,
1709 doc
: /* Alist of D-Bus buses we are polling for messages.
1711 The key is the symbol or string of the bus, and the value is the
1712 connection address. */);
1713 Vdbus_registered_buses
= Qnil
;
1715 DEFVAR_LISP ("dbus-registered-objects-table",
1716 Vdbus_registered_objects_table
,
1717 doc
: /* Hash table of registered functions for D-Bus.
1719 There are two different uses of the hash table: for accessing
1720 registered interfaces properties, targeted by signals or method calls,
1721 and for calling handlers in case of non-blocking method call returns.
1723 In the first case, the key in the hash table is the list (TYPE BUS
1724 INTERFACE MEMBER). TYPE is one of the Lisp symbols `:method',
1725 `:signal' or `:property'. BUS is either a Lisp symbol, `:system' or
1726 `:session', or a string denoting the bus address. INTERFACE is a
1727 string which denotes a D-Bus interface, and MEMBER, also a string, is
1728 either a method, a signal or a property INTERFACE is offering. All
1729 arguments but BUS must not be nil.
1731 The value in the hash table is a list of quadruple lists \((UNAME
1732 SERVICE PATH OBJECT [RULE]) ...). SERVICE is the service name as
1733 registered, UNAME is the corresponding unique name. In case of
1734 registered methods and properties, UNAME is nil. PATH is the object
1735 path of the sending object. All of them can be nil, which means a
1736 wildcard then. OBJECT is either the handler to be called when a D-Bus
1737 message, which matches the key criteria, arrives (TYPE `:method' and
1738 `:signal'), or a cons cell containing the value of the property (TYPE
1741 For entries of type `:signal', there is also a fifth element RULE,
1742 which keeps the match string the signal is registered with.
1744 In the second case, the key in the hash table is the list (:serial BUS
1745 SERIAL). BUS is either a Lisp symbol, `:system' or `:session', or a
1746 string denoting the bus address. SERIAL is the serial number of the
1747 non-blocking method call, a reply is expected. Both arguments must
1748 not be nil. The value in the hash table is HANDLER, the function to
1749 be called when the D-Bus reply message arrives. */);
1751 Lisp_Object args
[2];
1754 Vdbus_registered_objects_table
= Fmake_hash_table (2, args
);
1757 DEFVAR_LISP ("dbus-debug", Vdbus_debug
,
1758 doc
: /* If non-nil, debug messages of D-Bus bindings are raised. */);
1761 /* We can also set environment variable DBUS_VERBOSE=1 in order to
1762 see more traces. This requires libdbus-1 to be configured with
1763 --enable-verbose-mode. */
1768 Fprovide (intern_c_string ("dbusbind"), Qnil
);
1772 #endif /* HAVE_DBUS */