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