]> code.delx.au - gnu-emacs/blob - src/dbusbind.c
Update copyright year to 2016
[gnu-emacs] / src / dbusbind.c
1 /* Elisp bindings for D-Bus.
2 Copyright (C) 2007-2016 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
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.
10
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.
15
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/>. */
18
19 #include <config.h>
20
21 #ifdef HAVE_DBUS
22 #include <stdio.h>
23 #include <dbus/dbus.h>
24
25 #include "lisp.h"
26 #include "termhooks.h"
27 #include "keyboard.h"
28 #include "process.h"
29
30 #ifndef DBUS_NUM_MESSAGE_TYPES
31 #define DBUS_NUM_MESSAGE_TYPES 5
32 #endif
33
34
35 /* Some platforms define the symbol "interface", but we want to use it
36 * as a variable name below. */
37
38 #ifdef interface
39 #undef interface
40 #endif
41
42 \f
43 /* Alist of D-Bus buses we are polling for messages.
44 The key is the symbol or string of the bus, and the value is the
45 connection address. */
46 static Lisp_Object xd_registered_buses;
47
48 /* Whether we are reading a D-Bus event. */
49 static bool xd_in_read_queued_messages = 0;
50
51 \f
52 /* We use "xd_" and "XD_" as prefix for all internal symbols, because
53 we don't want to poison other namespaces with "dbus_". */
54
55 /* Raise a signal. If we are reading events, we cannot signal; we
56 throw to xd_read_queued_messages then. */
57 #define XD_SIGNAL1(arg) \
58 do { \
59 if (xd_in_read_queued_messages) \
60 Fthrow (Qdbus_error, Qnil); \
61 else \
62 xsignal1 (Qdbus_error, arg); \
63 } while (0)
64
65 #define XD_SIGNAL2(arg1, arg2) \
66 do { \
67 if (xd_in_read_queued_messages) \
68 Fthrow (Qdbus_error, Qnil); \
69 else \
70 xsignal2 (Qdbus_error, arg1, arg2); \
71 } while (0)
72
73 #define XD_SIGNAL3(arg1, arg2, arg3) \
74 do { \
75 if (xd_in_read_queued_messages) \
76 Fthrow (Qdbus_error, Qnil); \
77 else \
78 xsignal3 (Qdbus_error, arg1, arg2, arg3); \
79 } while (0)
80
81 /* Raise a Lisp error from a D-Bus ERROR. */
82 #define XD_ERROR(error) \
83 do { \
84 /* Remove the trailing newline. */ \
85 char const *mess = error.message; \
86 char const *nl = strchr (mess, '\n'); \
87 Lisp_Object err = make_string (mess, nl ? nl - mess : strlen (mess)); \
88 dbus_error_free (&error); \
89 XD_SIGNAL1 (err); \
90 } while (0)
91
92 /* Macros for debugging. In order to enable them, build with
93 "env MYCPPFLAGS='-DDBUS_DEBUG -Wall' make". */
94 #ifdef DBUS_DEBUG
95 #define XD_DEBUG_MESSAGE(...) \
96 do { \
97 char s[1024]; \
98 snprintf (s, sizeof s, __VA_ARGS__); \
99 if (!noninteractive) \
100 printf ("%s: %s\n", __func__, s); \
101 message ("%s: %s", __func__, s); \
102 } while (0)
103 #define XD_DEBUG_VALID_LISP_OBJECT_P(object) \
104 do { \
105 if (!valid_lisp_object_p (object)) \
106 { \
107 XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__); \
108 XD_SIGNAL1 (build_string ("Assertion failure")); \
109 } \
110 } while (0)
111
112 #else /* !DBUS_DEBUG */
113 # define XD_DEBUG_MESSAGE(...) \
114 do { \
115 if (!NILP (Vdbus_debug)) \
116 { \
117 char s[1024]; \
118 snprintf (s, sizeof s, __VA_ARGS__); \
119 message ("%s: %s", __func__, s); \
120 } \
121 } while (0)
122 # define XD_DEBUG_VALID_LISP_OBJECT_P(object)
123 #endif
124
125 /* Check whether TYPE is a basic DBusType. */
126 #ifdef HAVE_DBUS_TYPE_IS_VALID
127 #define XD_BASIC_DBUS_TYPE(type) \
128 (dbus_type_is_valid (type) && dbus_type_is_basic (type))
129 #else
130 #ifdef DBUS_TYPE_UNIX_FD
131 #define XD_BASIC_DBUS_TYPE(type) \
132 ((type == DBUS_TYPE_BYTE) \
133 || (type == DBUS_TYPE_BOOLEAN) \
134 || (type == DBUS_TYPE_INT16) \
135 || (type == DBUS_TYPE_UINT16) \
136 || (type == DBUS_TYPE_INT32) \
137 || (type == DBUS_TYPE_UINT32) \
138 || (type == DBUS_TYPE_INT64) \
139 || (type == DBUS_TYPE_UINT64) \
140 || (type == DBUS_TYPE_DOUBLE) \
141 || (type == DBUS_TYPE_STRING) \
142 || (type == DBUS_TYPE_OBJECT_PATH) \
143 || (type == DBUS_TYPE_SIGNATURE) \
144 || (type == DBUS_TYPE_UNIX_FD))
145 #else
146 #define XD_BASIC_DBUS_TYPE(type) \
147 ((type == DBUS_TYPE_BYTE) \
148 || (type == DBUS_TYPE_BOOLEAN) \
149 || (type == DBUS_TYPE_INT16) \
150 || (type == DBUS_TYPE_UINT16) \
151 || (type == DBUS_TYPE_INT32) \
152 || (type == DBUS_TYPE_UINT32) \
153 || (type == DBUS_TYPE_INT64) \
154 || (type == DBUS_TYPE_UINT64) \
155 || (type == DBUS_TYPE_DOUBLE) \
156 || (type == DBUS_TYPE_STRING) \
157 || (type == DBUS_TYPE_OBJECT_PATH) \
158 || (type == DBUS_TYPE_SIGNATURE))
159 #endif
160 #endif
161
162 /* This was a macro. On Solaris 2.11 it was said to compile for
163 hours, when optimization is enabled. So we have transferred it into
164 a function. */
165 /* Determine the DBusType of a given Lisp symbol. OBJECT must be one
166 of the predefined D-Bus type symbols. */
167 static int
168 xd_symbol_to_dbus_type (Lisp_Object object)
169 {
170 return
171 ((EQ (object, QCdbus_type_byte)) ? DBUS_TYPE_BYTE
172 : (EQ (object, QCdbus_type_boolean)) ? DBUS_TYPE_BOOLEAN
173 : (EQ (object, QCdbus_type_int16)) ? DBUS_TYPE_INT16
174 : (EQ (object, QCdbus_type_uint16)) ? DBUS_TYPE_UINT16
175 : (EQ (object, QCdbus_type_int32)) ? DBUS_TYPE_INT32
176 : (EQ (object, QCdbus_type_uint32)) ? DBUS_TYPE_UINT32
177 : (EQ (object, QCdbus_type_int64)) ? DBUS_TYPE_INT64
178 : (EQ (object, QCdbus_type_uint64)) ? DBUS_TYPE_UINT64
179 : (EQ (object, QCdbus_type_double)) ? DBUS_TYPE_DOUBLE
180 : (EQ (object, QCdbus_type_string)) ? DBUS_TYPE_STRING
181 : (EQ (object, QCdbus_type_object_path)) ? DBUS_TYPE_OBJECT_PATH
182 : (EQ (object, QCdbus_type_signature)) ? DBUS_TYPE_SIGNATURE
183 #ifdef DBUS_TYPE_UNIX_FD
184 : (EQ (object, QCdbus_type_unix_fd)) ? DBUS_TYPE_UNIX_FD
185 #endif
186 : (EQ (object, QCdbus_type_array)) ? DBUS_TYPE_ARRAY
187 : (EQ (object, QCdbus_type_variant)) ? DBUS_TYPE_VARIANT
188 : (EQ (object, QCdbus_type_struct)) ? DBUS_TYPE_STRUCT
189 : (EQ (object, QCdbus_type_dict_entry)) ? DBUS_TYPE_DICT_ENTRY
190 : DBUS_TYPE_INVALID);
191 }
192
193 /* Check whether a Lisp symbol is a predefined D-Bus type symbol. */
194 #define XD_DBUS_TYPE_P(object) \
195 (SYMBOLP (object) && ((xd_symbol_to_dbus_type (object) != DBUS_TYPE_INVALID)))
196
197 /* Determine the DBusType of a given Lisp OBJECT. It is used to
198 convert Lisp objects, being arguments of `dbus-call-method' or
199 `dbus-send-signal', into corresponding C values appended as
200 arguments to a D-Bus message. */
201 #define XD_OBJECT_TO_DBUS_TYPE(object) \
202 ((EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN \
203 : (NATNUMP (object)) ? DBUS_TYPE_UINT32 \
204 : (INTEGERP (object)) ? DBUS_TYPE_INT32 \
205 : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \
206 : (STRINGP (object)) ? DBUS_TYPE_STRING \
207 : (XD_DBUS_TYPE_P (object)) ? xd_symbol_to_dbus_type (object) \
208 : (CONSP (object)) \
209 ? ((XD_DBUS_TYPE_P (CAR_SAFE (object))) \
210 ? ((XD_BASIC_DBUS_TYPE (xd_symbol_to_dbus_type (CAR_SAFE (object)))) \
211 ? DBUS_TYPE_ARRAY \
212 : xd_symbol_to_dbus_type (CAR_SAFE (object))) \
213 : DBUS_TYPE_ARRAY) \
214 : DBUS_TYPE_INVALID)
215
216 /* Return a list pointer which does not have a Lisp symbol as car. */
217 #define XD_NEXT_VALUE(object) \
218 ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object)
219
220 /* Transform the message type to its string representation for debug
221 messages. */
222 #define XD_MESSAGE_TYPE_TO_STRING(mtype) \
223 ((mtype == DBUS_MESSAGE_TYPE_INVALID) \
224 ? "DBUS_MESSAGE_TYPE_INVALID" \
225 : (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) \
226 ? "DBUS_MESSAGE_TYPE_METHOD_CALL" \
227 : (mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) \
228 ? "DBUS_MESSAGE_TYPE_METHOD_RETURN" \
229 : (mtype == DBUS_MESSAGE_TYPE_ERROR) \
230 ? "DBUS_MESSAGE_TYPE_ERROR" \
231 : "DBUS_MESSAGE_TYPE_SIGNAL")
232
233 /* Transform the object to its string representation for debug
234 messages. */
235 static char *
236 XD_OBJECT_TO_STRING (Lisp_Object object)
237 {
238 AUTO_STRING (format, "%s");
239 return SSDATA (CALLN (Fformat, format, object));
240 }
241
242 #define XD_DBUS_VALIDATE_BUS_ADDRESS(bus) \
243 do { \
244 char const *session_bus_address = getenv ("DBUS_SESSION_BUS_ADDRESS"); \
245 if (STRINGP (bus)) \
246 { \
247 DBusAddressEntry **entries; \
248 int len; \
249 DBusError derror; \
250 dbus_error_init (&derror); \
251 if (!dbus_parse_address (SSDATA (bus), &entries, &len, &derror)) \
252 XD_ERROR (derror); \
253 /* Cleanup. */ \
254 dbus_error_free (&derror); \
255 dbus_address_entries_free (entries); \
256 /* Canonicalize session bus address. */ \
257 if ((session_bus_address != NULL) \
258 && (!NILP (Fstring_equal \
259 (bus, build_string (session_bus_address))))) \
260 bus = QCdbus_session_bus; \
261 } \
262 \
263 else \
264 { \
265 CHECK_SYMBOL (bus); \
266 if (!(EQ (bus, QCdbus_system_bus) || EQ (bus, QCdbus_session_bus))) \
267 XD_SIGNAL2 (build_string ("Wrong bus name"), bus); \
268 /* We do not want to have an autolaunch for the session bus. */ \
269 if (EQ (bus, QCdbus_session_bus) && session_bus_address == NULL) \
270 XD_SIGNAL2 (build_string ("No connection to bus"), bus); \
271 } \
272 } while (0)
273
274 #if (HAVE_DBUS_VALIDATE_BUS_NAME || HAVE_DBUS_VALIDATE_PATH \
275 || HAVE_DBUS_VALIDATE_INTERFACE || HAVE_DBUS_VALIDATE_MEMBER)
276 #define XD_DBUS_VALIDATE_OBJECT(object, func) \
277 do { \
278 if (!NILP (object)) \
279 { \
280 DBusError derror; \
281 CHECK_STRING (object); \
282 dbus_error_init (&derror); \
283 if (!func (SSDATA (object), &derror)) \
284 XD_ERROR (derror); \
285 /* Cleanup. */ \
286 dbus_error_free (&derror); \
287 } \
288 } while (0)
289 #endif
290
291 #if HAVE_DBUS_VALIDATE_BUS_NAME
292 #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \
293 XD_DBUS_VALIDATE_OBJECT(bus_name, dbus_validate_bus_name);
294 #else
295 #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \
296 if (!NILP (bus_name)) CHECK_STRING (bus_name);
297 #endif
298
299 #if HAVE_DBUS_VALIDATE_PATH
300 #define XD_DBUS_VALIDATE_PATH(path) \
301 XD_DBUS_VALIDATE_OBJECT(path, dbus_validate_path);
302 #else
303 #define XD_DBUS_VALIDATE_PATH(path) \
304 if (!NILP (path)) CHECK_STRING (path);
305 #endif
306
307 #if HAVE_DBUS_VALIDATE_INTERFACE
308 #define XD_DBUS_VALIDATE_INTERFACE(interface) \
309 XD_DBUS_VALIDATE_OBJECT(interface, dbus_validate_interface);
310 #else
311 #define XD_DBUS_VALIDATE_INTERFACE(interface) \
312 if (!NILP (interface)) CHECK_STRING (interface);
313 #endif
314
315 #if HAVE_DBUS_VALIDATE_MEMBER
316 #define XD_DBUS_VALIDATE_MEMBER(member) \
317 XD_DBUS_VALIDATE_OBJECT(member, dbus_validate_member);
318 #else
319 #define XD_DBUS_VALIDATE_MEMBER(member) \
320 if (!NILP (member)) CHECK_STRING (member);
321 #endif
322
323 /* Append to SIGNATURE a copy of X, making sure SIGNATURE does
324 not become too long. */
325 static void
326 xd_signature_cat (char *signature, char const *x)
327 {
328 ptrdiff_t siglen = strlen (signature);
329 ptrdiff_t xlen = strlen (x);
330 if (DBUS_MAXIMUM_SIGNATURE_LENGTH - xlen <= siglen)
331 string_overflow ();
332 strcpy (signature + siglen, x);
333 }
334
335 /* Compute SIGNATURE of OBJECT. It must have a form that it can be
336 used in dbus_message_iter_open_container. DTYPE is the DBusType
337 the object is related to. It is passed as argument, because it
338 cannot be detected in basic type objects, when they are preceded by
339 a type symbol. PARENT_TYPE is the DBusType of a container this
340 signature is embedded, or DBUS_TYPE_INVALID. It is needed for the
341 check that DBUS_TYPE_DICT_ENTRY occurs only as array element. */
342 static void
343 xd_signature (char *signature, int dtype, int parent_type, Lisp_Object object)
344 {
345 int subtype;
346 Lisp_Object elt;
347 char const *subsig;
348 int subsiglen;
349 char x[DBUS_MAXIMUM_SIGNATURE_LENGTH];
350
351 elt = object;
352
353 switch (dtype)
354 {
355 case DBUS_TYPE_BYTE:
356 case DBUS_TYPE_UINT16:
357 CHECK_NATNUM (object);
358 sprintf (signature, "%c", dtype);
359 break;
360
361 case DBUS_TYPE_BOOLEAN:
362 if (!EQ (object, Qt) && !EQ (object, Qnil))
363 wrong_type_argument (intern ("booleanp"), object);
364 sprintf (signature, "%c", dtype);
365 break;
366
367 case DBUS_TYPE_INT16:
368 CHECK_NUMBER (object);
369 sprintf (signature, "%c", dtype);
370 break;
371
372 case DBUS_TYPE_UINT32:
373 case DBUS_TYPE_UINT64:
374 #ifdef DBUS_TYPE_UNIX_FD
375 case DBUS_TYPE_UNIX_FD:
376 #endif
377 case DBUS_TYPE_INT32:
378 case DBUS_TYPE_INT64:
379 case DBUS_TYPE_DOUBLE:
380 CHECK_NUMBER_OR_FLOAT (object);
381 sprintf (signature, "%c", dtype);
382 break;
383
384 case DBUS_TYPE_STRING:
385 case DBUS_TYPE_OBJECT_PATH:
386 case DBUS_TYPE_SIGNATURE:
387 CHECK_STRING (object);
388 sprintf (signature, "%c", dtype);
389 break;
390
391 case DBUS_TYPE_ARRAY:
392 /* Check that all list elements have the same D-Bus type. For
393 complex element types, we just check the container type, not
394 the whole element's signature. */
395 CHECK_CONS (object);
396
397 /* Type symbol is optional. */
398 if (EQ (QCdbus_type_array, CAR_SAFE (elt)))
399 elt = XD_NEXT_VALUE (elt);
400
401 /* If the array is empty, DBUS_TYPE_STRING is the default
402 element type. */
403 if (NILP (elt))
404 {
405 subtype = DBUS_TYPE_STRING;
406 subsig = DBUS_TYPE_STRING_AS_STRING;
407 }
408 else
409 {
410 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
411 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
412 subsig = x;
413 }
414
415 /* If the element type is DBUS_TYPE_SIGNATURE, and this is the
416 only element, the value of this element is used as the
417 array's element signature. */
418 if ((subtype == DBUS_TYPE_SIGNATURE)
419 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt)))
420 && NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
421 subsig = SSDATA (CAR_SAFE (XD_NEXT_VALUE (elt)));
422
423 while (!NILP (elt))
424 {
425 if (subtype != XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)))
426 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (elt));
427 elt = CDR_SAFE (XD_NEXT_VALUE (elt));
428 }
429
430 subsiglen = snprintf (signature, DBUS_MAXIMUM_SIGNATURE_LENGTH,
431 "%c%s", dtype, subsig);
432 if (! (0 <= subsiglen && subsiglen < DBUS_MAXIMUM_SIGNATURE_LENGTH))
433 string_overflow ();
434 break;
435
436 case DBUS_TYPE_VARIANT:
437 /* Check that there is exactly one list element. */
438 CHECK_CONS (object);
439
440 elt = XD_NEXT_VALUE (elt);
441 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
442 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
443
444 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
445 wrong_type_argument (intern ("D-Bus"),
446 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt))));
447
448 sprintf (signature, "%c", dtype);
449 break;
450
451 case DBUS_TYPE_STRUCT:
452 /* A struct list might contain any number of elements with
453 different types. No further check needed. */
454 CHECK_CONS (object);
455
456 elt = XD_NEXT_VALUE (elt);
457
458 /* Compose the signature from the elements. It is enclosed by
459 parentheses. */
460 sprintf (signature, "%c", DBUS_STRUCT_BEGIN_CHAR );
461 while (!NILP (elt))
462 {
463 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
464 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
465 xd_signature_cat (signature, x);
466 elt = CDR_SAFE (XD_NEXT_VALUE (elt));
467 }
468 xd_signature_cat (signature, DBUS_STRUCT_END_CHAR_AS_STRING);
469 break;
470
471 case DBUS_TYPE_DICT_ENTRY:
472 /* Check that there are exactly two list elements, and the first
473 one is of basic type. The dictionary entry itself must be an
474 element of an array. */
475 CHECK_CONS (object);
476
477 /* Check the parent object type. */
478 if (parent_type != DBUS_TYPE_ARRAY)
479 wrong_type_argument (intern ("D-Bus"), object);
480
481 /* Compose the signature from the elements. It is enclosed by
482 curly braces. */
483 sprintf (signature, "%c", DBUS_DICT_ENTRY_BEGIN_CHAR);
484
485 /* First element. */
486 elt = XD_NEXT_VALUE (elt);
487 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
488 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
489 xd_signature_cat (signature, x);
490
491 if (!XD_BASIC_DBUS_TYPE (subtype))
492 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt)));
493
494 /* Second element. */
495 elt = CDR_SAFE (XD_NEXT_VALUE (elt));
496 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
497 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
498 xd_signature_cat (signature, x);
499
500 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
501 wrong_type_argument (intern ("D-Bus"),
502 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt))));
503
504 /* Closing signature. */
505 xd_signature_cat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
506 break;
507
508 default:
509 wrong_type_argument (intern ("D-Bus"), object);
510 }
511
512 XD_DEBUG_MESSAGE ("%s", signature);
513 }
514
515 /* Convert X to a signed integer with bounds LO and HI. */
516 static intmax_t
517 xd_extract_signed (Lisp_Object x, intmax_t lo, intmax_t hi)
518 {
519 CHECK_NUMBER_OR_FLOAT (x);
520 if (INTEGERP (x))
521 {
522 if (lo <= XINT (x) && XINT (x) <= hi)
523 return XINT (x);
524 }
525 else
526 {
527 double d = XFLOAT_DATA (x);
528 if (lo <= d && d <= hi)
529 {
530 intmax_t n = d;
531 if (n == d)
532 return n;
533 }
534 }
535 if (xd_in_read_queued_messages)
536 Fthrow (Qdbus_error, Qnil);
537 else
538 args_out_of_range_3 (x,
539 make_fixnum_or_float (lo),
540 make_fixnum_or_float (hi));
541 }
542
543 /* Convert X to an unsigned integer with bounds 0 and HI. */
544 static uintmax_t
545 xd_extract_unsigned (Lisp_Object x, uintmax_t hi)
546 {
547 CHECK_NUMBER_OR_FLOAT (x);
548 if (INTEGERP (x))
549 {
550 if (0 <= XINT (x) && XINT (x) <= hi)
551 return XINT (x);
552 }
553 else
554 {
555 double d = XFLOAT_DATA (x);
556 if (0 <= d && d <= hi)
557 {
558 uintmax_t n = d;
559 if (n == d)
560 return n;
561 }
562 }
563 if (xd_in_read_queued_messages)
564 Fthrow (Qdbus_error, Qnil);
565 else
566 args_out_of_range_3 (x, make_number (0), make_fixnum_or_float (hi));
567 }
568
569 /* Append C value, extracted from Lisp OBJECT, to iteration ITER.
570 DTYPE must be a valid DBusType. It is used to convert Lisp
571 objects, being arguments of `dbus-call-method' or
572 `dbus-send-signal', into corresponding C values appended as
573 arguments to a D-Bus message. */
574 static void
575 xd_append_arg (int dtype, Lisp_Object object, DBusMessageIter *iter)
576 {
577 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
578 DBusMessageIter subiter;
579
580 if (XD_BASIC_DBUS_TYPE (dtype))
581 switch (dtype)
582 {
583 case DBUS_TYPE_BYTE:
584 CHECK_NATNUM (object);
585 {
586 unsigned char val = XFASTINT (object) & 0xFF;
587 XD_DEBUG_MESSAGE ("%c %u", dtype, val);
588 if (!dbus_message_iter_append_basic (iter, dtype, &val))
589 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
590 return;
591 }
592
593 case DBUS_TYPE_BOOLEAN:
594 {
595 dbus_bool_t val = (NILP (object)) ? FALSE : TRUE;
596 XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
597 if (!dbus_message_iter_append_basic (iter, dtype, &val))
598 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
599 return;
600 }
601
602 case DBUS_TYPE_INT16:
603 {
604 dbus_int16_t val =
605 xd_extract_signed (object,
606 TYPE_MINIMUM (dbus_int16_t),
607 TYPE_MAXIMUM (dbus_int16_t));
608 int pval = val;
609 XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
610 if (!dbus_message_iter_append_basic (iter, dtype, &val))
611 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
612 return;
613 }
614
615 case DBUS_TYPE_UINT16:
616 {
617 dbus_uint16_t val =
618 xd_extract_unsigned (object,
619 TYPE_MAXIMUM (dbus_uint16_t));
620 unsigned int pval = val;
621 XD_DEBUG_MESSAGE ("%c %u", dtype, pval);
622 if (!dbus_message_iter_append_basic (iter, dtype, &val))
623 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
624 return;
625 }
626
627 case DBUS_TYPE_INT32:
628 {
629 dbus_int32_t val =
630 xd_extract_signed (object,
631 TYPE_MINIMUM (dbus_int32_t),
632 TYPE_MAXIMUM (dbus_int32_t));
633 int pval = val;
634 XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
635 if (!dbus_message_iter_append_basic (iter, dtype, &val))
636 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
637 return;
638 }
639
640 case DBUS_TYPE_UINT32:
641 #ifdef DBUS_TYPE_UNIX_FD
642 case DBUS_TYPE_UNIX_FD:
643 #endif
644 {
645 dbus_uint32_t val =
646 xd_extract_unsigned (object,
647 TYPE_MAXIMUM (dbus_uint32_t));
648 unsigned int pval = val;
649 XD_DEBUG_MESSAGE ("%c %u", dtype, pval);
650 if (!dbus_message_iter_append_basic (iter, dtype, &val))
651 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
652 return;
653 }
654
655 case DBUS_TYPE_INT64:
656 {
657 dbus_int64_t val =
658 xd_extract_signed (object,
659 TYPE_MINIMUM (dbus_int64_t),
660 TYPE_MAXIMUM (dbus_int64_t));
661 printmax_t pval = val;
662 XD_DEBUG_MESSAGE ("%c %"pMd, dtype, pval);
663 if (!dbus_message_iter_append_basic (iter, dtype, &val))
664 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
665 return;
666 }
667
668 case DBUS_TYPE_UINT64:
669 {
670 dbus_uint64_t val =
671 xd_extract_unsigned (object,
672 TYPE_MAXIMUM (dbus_uint64_t));
673 uprintmax_t pval = val;
674 XD_DEBUG_MESSAGE ("%c %"pMu, dtype, pval);
675 if (!dbus_message_iter_append_basic (iter, dtype, &val))
676 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
677 return;
678 }
679
680 case DBUS_TYPE_DOUBLE:
681 {
682 double val = extract_float (object);
683 XD_DEBUG_MESSAGE ("%c %f", dtype, val);
684 if (!dbus_message_iter_append_basic (iter, dtype, &val))
685 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
686 return;
687 }
688
689 case DBUS_TYPE_STRING:
690 case DBUS_TYPE_OBJECT_PATH:
691 case DBUS_TYPE_SIGNATURE:
692 CHECK_STRING (object);
693 {
694 /* We need to send a valid UTF-8 string. We could encode `object'
695 but by not encoding it, we guarantee it's valid utf-8, even if
696 it contains eight-bit-bytes. Of course, you can still send
697 manually-crafted junk by passing a unibyte string. */
698 char *val = SSDATA (object);
699 XD_DEBUG_MESSAGE ("%c %s", dtype, val);
700 if (!dbus_message_iter_append_basic (iter, dtype, &val))
701 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
702 return;
703 }
704 }
705
706 else /* Compound types. */
707 {
708
709 /* All compound types except array have a type symbol. For
710 array, it is optional. Skip it. */
711 if (!XD_BASIC_DBUS_TYPE (XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object))))
712 object = XD_NEXT_VALUE (object);
713
714 /* Open new subiteration. */
715 switch (dtype)
716 {
717 case DBUS_TYPE_ARRAY:
718 /* An array has only elements of the same type. So it is
719 sufficient to check the first element's signature
720 only. */
721
722 if (NILP (object))
723 /* If the array is empty, DBUS_TYPE_STRING is the default
724 element type. */
725 strcpy (signature, DBUS_TYPE_STRING_AS_STRING);
726
727 else
728 /* If the element type is DBUS_TYPE_SIGNATURE, and this is
729 the only element, the value of this element is used as
730 the array's element signature. */
731 if ((XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object))
732 == DBUS_TYPE_SIGNATURE)
733 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object)))
734 && NILP (CDR_SAFE (XD_NEXT_VALUE (object))))
735 {
736 lispstpcpy (signature, CAR_SAFE (XD_NEXT_VALUE (object)));
737 object = CDR_SAFE (XD_NEXT_VALUE (object));
738 }
739
740 else
741 xd_signature (signature,
742 XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)),
743 dtype, CAR_SAFE (XD_NEXT_VALUE (object)));
744
745 XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature,
746 XD_OBJECT_TO_STRING (object));
747 if (!dbus_message_iter_open_container (iter, dtype,
748 signature, &subiter))
749 XD_SIGNAL3 (build_string ("Cannot open container"),
750 make_number (dtype), build_string (signature));
751 break;
752
753 case DBUS_TYPE_VARIANT:
754 /* A variant has just one element. */
755 xd_signature (signature, XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)),
756 dtype, CAR_SAFE (XD_NEXT_VALUE (object)));
757
758 XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature,
759 XD_OBJECT_TO_STRING (object));
760 if (!dbus_message_iter_open_container (iter, dtype,
761 signature, &subiter))
762 XD_SIGNAL3 (build_string ("Cannot open container"),
763 make_number (dtype), build_string (signature));
764 break;
765
766 case DBUS_TYPE_STRUCT:
767 case DBUS_TYPE_DICT_ENTRY:
768 /* These containers do not require a signature. */
769 XD_DEBUG_MESSAGE ("%c %s", dtype, XD_OBJECT_TO_STRING (object));
770 if (!dbus_message_iter_open_container (iter, dtype, NULL, &subiter))
771 XD_SIGNAL2 (build_string ("Cannot open container"),
772 make_number (dtype));
773 break;
774 }
775
776 /* Loop over list elements. */
777 while (!NILP (object))
778 {
779 dtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object));
780 object = XD_NEXT_VALUE (object);
781
782 xd_append_arg (dtype, CAR_SAFE (object), &subiter);
783
784 object = CDR_SAFE (object);
785 }
786
787 /* Close the subiteration. */
788 if (!dbus_message_iter_close_container (iter, &subiter))
789 XD_SIGNAL2 (build_string ("Cannot close container"),
790 make_number (dtype));
791 }
792 }
793
794 /* Retrieve C value from a DBusMessageIter structure ITER, and return
795 a converted Lisp object. The type DTYPE of the argument of the
796 D-Bus message must be a valid DBusType. Compound D-Bus types
797 result always in a Lisp list. */
798 static Lisp_Object
799 xd_retrieve_arg (int dtype, DBusMessageIter *iter)
800 {
801
802 switch (dtype)
803 {
804 case DBUS_TYPE_BYTE:
805 {
806 unsigned int val;
807 dbus_message_iter_get_basic (iter, &val);
808 val = val & 0xFF;
809 XD_DEBUG_MESSAGE ("%c %u", dtype, val);
810 return make_number (val);
811 }
812
813 case DBUS_TYPE_BOOLEAN:
814 {
815 dbus_bool_t val;
816 dbus_message_iter_get_basic (iter, &val);
817 XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
818 return (val == FALSE) ? Qnil : Qt;
819 }
820
821 case DBUS_TYPE_INT16:
822 {
823 dbus_int16_t val;
824 int pval;
825 dbus_message_iter_get_basic (iter, &val);
826 pval = val;
827 XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
828 return make_number (val);
829 }
830
831 case DBUS_TYPE_UINT16:
832 {
833 dbus_uint16_t val;
834 int pval;
835 dbus_message_iter_get_basic (iter, &val);
836 pval = val;
837 XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
838 return make_number (val);
839 }
840
841 case DBUS_TYPE_INT32:
842 {
843 dbus_int32_t val;
844 int pval;
845 dbus_message_iter_get_basic (iter, &val);
846 pval = val;
847 XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
848 return make_fixnum_or_float (val);
849 }
850
851 case DBUS_TYPE_UINT32:
852 #ifdef DBUS_TYPE_UNIX_FD
853 case DBUS_TYPE_UNIX_FD:
854 #endif
855 {
856 dbus_uint32_t val;
857 unsigned int pval;
858 dbus_message_iter_get_basic (iter, &val);
859 pval = val;
860 XD_DEBUG_MESSAGE ("%c %u", dtype, pval);
861 return make_fixnum_or_float (val);
862 }
863
864 case DBUS_TYPE_INT64:
865 {
866 dbus_int64_t val;
867 printmax_t pval;
868 dbus_message_iter_get_basic (iter, &val);
869 pval = val;
870 XD_DEBUG_MESSAGE ("%c %"pMd, dtype, pval);
871 return make_fixnum_or_float (val);
872 }
873
874 case DBUS_TYPE_UINT64:
875 {
876 dbus_uint64_t val;
877 uprintmax_t pval;
878 dbus_message_iter_get_basic (iter, &val);
879 pval = val;
880 XD_DEBUG_MESSAGE ("%c %"pMu, dtype, pval);
881 return make_fixnum_or_float (val);
882 }
883
884 case DBUS_TYPE_DOUBLE:
885 {
886 double val;
887 dbus_message_iter_get_basic (iter, &val);
888 XD_DEBUG_MESSAGE ("%c %f", dtype, val);
889 return make_float (val);
890 }
891
892 case DBUS_TYPE_STRING:
893 case DBUS_TYPE_OBJECT_PATH:
894 case DBUS_TYPE_SIGNATURE:
895 {
896 char *val;
897 dbus_message_iter_get_basic (iter, &val);
898 XD_DEBUG_MESSAGE ("%c %s", dtype, val);
899 return build_string (val);
900 }
901
902 case DBUS_TYPE_ARRAY:
903 case DBUS_TYPE_VARIANT:
904 case DBUS_TYPE_STRUCT:
905 case DBUS_TYPE_DICT_ENTRY:
906 {
907 Lisp_Object result;
908 DBusMessageIter subiter;
909 int subtype;
910 result = Qnil;
911 dbus_message_iter_recurse (iter, &subiter);
912 while ((subtype = dbus_message_iter_get_arg_type (&subiter))
913 != DBUS_TYPE_INVALID)
914 {
915 result = Fcons (xd_retrieve_arg (subtype, &subiter), result);
916 dbus_message_iter_next (&subiter);
917 }
918 XD_DEBUG_MESSAGE ("%c %s", dtype, XD_OBJECT_TO_STRING (result));
919 return Fnreverse (result);
920 }
921
922 default:
923 XD_DEBUG_MESSAGE ("DBusType '%c' not supported", dtype);
924 return Qnil;
925 }
926 }
927
928 /* Return the number of references of the shared CONNECTION. */
929 static ptrdiff_t
930 xd_get_connection_references (DBusConnection *connection)
931 {
932 ptrdiff_t *refcount;
933
934 /* We cannot access the DBusConnection structure, it is not public.
935 But we know, that the reference counter is the first field in
936 that structure. */
937 refcount = (void *) &connection;
938 refcount = (void *) *refcount;
939 return *refcount;
940 }
941
942 /* Convert a Lisp D-Bus object to a pointer. */
943 static DBusConnection*
944 xd_lisp_dbus_to_dbus (Lisp_Object bus)
945 {
946 return (DBusConnection *) (intptr_t) XFASTINT (bus);
947 }
948
949 /* Return D-Bus connection address. BUS is either a Lisp symbol,
950 :system or :session, or a string denoting the bus address. */
951 static DBusConnection *
952 xd_get_connection_address (Lisp_Object bus)
953 {
954 DBusConnection *connection;
955 Lisp_Object val;
956
957 val = CDR_SAFE (Fassoc (bus, xd_registered_buses));
958 if (NILP (val))
959 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
960 else
961 connection = xd_lisp_dbus_to_dbus (val);
962
963 if (!dbus_connection_get_is_connected (connection))
964 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
965
966 return connection;
967 }
968
969 /* Return the file descriptor for WATCH, -1 if not found. */
970 static int
971 xd_find_watch_fd (DBusWatch *watch)
972 {
973 #if HAVE_DBUS_WATCH_GET_UNIX_FD
974 /* TODO: Reverse these on w32, which prefers the opposite. */
975 int fd = dbus_watch_get_unix_fd (watch);
976 if (fd == -1)
977 fd = dbus_watch_get_socket (watch);
978 #else
979 int fd = dbus_watch_get_fd (watch);
980 #endif
981 return fd;
982 }
983
984 /* Prototype. */
985 static void xd_read_queued_messages (int fd, void *data);
986
987 /* Start monitoring WATCH for possible I/O. */
988 static dbus_bool_t
989 xd_add_watch (DBusWatch *watch, void *data)
990 {
991 unsigned int flags = dbus_watch_get_flags (watch);
992 int fd = xd_find_watch_fd (watch);
993
994 XD_DEBUG_MESSAGE ("fd %d, write %u, enabled %u",
995 fd, flags & DBUS_WATCH_WRITABLE,
996 dbus_watch_get_enabled (watch));
997
998 if (fd == -1)
999 return FALSE;
1000
1001 if (dbus_watch_get_enabled (watch))
1002 {
1003 if (flags & DBUS_WATCH_WRITABLE)
1004 add_write_fd (fd, xd_read_queued_messages, data);
1005 if (flags & DBUS_WATCH_READABLE)
1006 add_read_fd (fd, xd_read_queued_messages, data);
1007 }
1008 return TRUE;
1009 }
1010
1011 /* Stop monitoring WATCH for possible I/O.
1012 DATA is the used bus, either a string or QCdbus_system_bus or
1013 QCdbus_session_bus. */
1014 static void
1015 xd_remove_watch (DBusWatch *watch, void *data)
1016 {
1017 unsigned int flags = dbus_watch_get_flags (watch);
1018 int fd = xd_find_watch_fd (watch);
1019
1020 XD_DEBUG_MESSAGE ("fd %d", fd);
1021
1022 if (fd == -1)
1023 return;
1024
1025 /* Unset session environment. */
1026 #if 0
1027 /* This is buggy, since unsetenv is not thread-safe. */
1028 if (XSYMBOL (QCdbus_session_bus) == data)
1029 {
1030 XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
1031 unsetenv ("DBUS_SESSION_BUS_ADDRESS");
1032 }
1033 #endif
1034
1035 if (flags & DBUS_WATCH_WRITABLE)
1036 delete_write_fd (fd);
1037 if (flags & DBUS_WATCH_READABLE)
1038 delete_read_fd (fd);
1039 }
1040
1041 /* Toggle monitoring WATCH for possible I/O. */
1042 static void
1043 xd_toggle_watch (DBusWatch *watch, void *data)
1044 {
1045 if (dbus_watch_get_enabled (watch))
1046 xd_add_watch (watch, data);
1047 else
1048 xd_remove_watch (watch, data);
1049 }
1050
1051 /* Close connection to D-Bus BUS. */
1052 static void
1053 xd_close_bus (Lisp_Object bus)
1054 {
1055 DBusConnection *connection;
1056 Lisp_Object val;
1057 Lisp_Object busobj;
1058
1059 /* Check whether we are connected. */
1060 val = Fassoc (bus, xd_registered_buses);
1061 if (NILP (val))
1062 return;
1063
1064 busobj = CDR_SAFE (val);
1065 if (NILP (busobj)) {
1066 xd_registered_buses = Fdelete (val, xd_registered_buses);
1067 return;
1068 }
1069
1070 /* Retrieve bus address. */
1071 connection = xd_lisp_dbus_to_dbus (busobj);
1072
1073 if (xd_get_connection_references (connection) == 1)
1074 {
1075 /* Close connection, if there isn't another shared application. */
1076 XD_DEBUG_MESSAGE ("Close connection to bus %s",
1077 XD_OBJECT_TO_STRING (bus));
1078 dbus_connection_close (connection);
1079
1080 xd_registered_buses = Fdelete (val, xd_registered_buses);
1081 }
1082
1083 else
1084 /* Decrement reference count. */
1085 dbus_connection_unref (connection);
1086
1087 /* Return. */
1088 return;
1089 }
1090
1091 DEFUN ("dbus--init-bus", Fdbus__init_bus, Sdbus__init_bus, 1, 2, 0,
1092 doc: /* Establish the connection to D-Bus BUS.
1093
1094 This function is dbus internal. You almost certainly want to use
1095 `dbus-init-bus'.
1096
1097 BUS can be either the symbol `:system' or the symbol `:session', or it
1098 can be a string denoting the address of the corresponding bus. For
1099 the system and session buses, this function is called when loading
1100 `dbus.el', there is no need to call it again.
1101
1102 The function returns a number, which counts the connections this Emacs
1103 session has established to the BUS under the same unique name (see
1104 `dbus-get-unique-name'). It depends on the libraries Emacs is linked
1105 with, and on the environment Emacs is running. For example, if Emacs
1106 is linked with the gtk toolkit, and it runs in a GTK-aware environment
1107 like Gnome, another connection might already be established.
1108
1109 When PRIVATE is non-nil, a new connection is established instead of
1110 reusing an existing one. It results in a new unique name at the bus.
1111 This can be used, if it is necessary to distinguish from another
1112 connection used in the same Emacs process, like the one established by
1113 GTK+. It should be used with care for at least the `:system' and
1114 `:session' buses, because other Emacs Lisp packages might already use
1115 this connection to those buses. */)
1116 (Lisp_Object bus, Lisp_Object private)
1117 {
1118 DBusConnection *connection;
1119 DBusError derror;
1120 Lisp_Object val;
1121 ptrdiff_t refcount;
1122
1123 /* Check parameter. */
1124 XD_DBUS_VALIDATE_BUS_ADDRESS (bus);
1125
1126 /* Close bus if it is already open. */
1127 xd_close_bus (bus);
1128
1129 /* Check, whether we are still connected. */
1130 val = Fassoc (bus, xd_registered_buses);
1131 if (!NILP (val))
1132 {
1133 connection = xd_get_connection_address (bus);
1134 dbus_connection_ref (connection);
1135 }
1136
1137 else
1138 {
1139 /* Initialize. */
1140 dbus_error_init (&derror);
1141
1142 /* Open the connection. */
1143 if (STRINGP (bus))
1144 if (NILP (private))
1145 connection = dbus_connection_open (SSDATA (bus), &derror);
1146 else
1147 connection = dbus_connection_open_private (SSDATA (bus), &derror);
1148
1149 else
1150 if (NILP (private))
1151 connection = dbus_bus_get (EQ (bus, QCdbus_system_bus)
1152 ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION,
1153 &derror);
1154 else
1155 connection = dbus_bus_get_private (EQ (bus, QCdbus_system_bus)
1156 ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION,
1157 &derror);
1158
1159 if (dbus_error_is_set (&derror))
1160 XD_ERROR (derror);
1161
1162 if (connection == NULL)
1163 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
1164
1165 /* If it is not the system or session bus, we must register
1166 ourselves. Otherwise, we have called dbus_bus_get, which has
1167 configured us to exit if the connection closes - we undo this
1168 setting. */
1169 if (STRINGP (bus))
1170 dbus_bus_register (connection, &derror);
1171 else
1172 dbus_connection_set_exit_on_disconnect (connection, FALSE);
1173
1174 if (dbus_error_is_set (&derror))
1175 XD_ERROR (derror);
1176
1177 /* Add the watch functions. We pass also the bus as data, in
1178 order to distinguish between the buses in xd_remove_watch. */
1179 if (!dbus_connection_set_watch_functions (connection,
1180 xd_add_watch,
1181 xd_remove_watch,
1182 xd_toggle_watch,
1183 SYMBOLP (bus)
1184 ? (void *) XSYMBOL (bus)
1185 : (void *) XSTRING (bus),
1186 NULL))
1187 XD_SIGNAL1 (build_string ("Cannot add watch functions"));
1188
1189 /* Add bus to list of registered buses. */
1190 XSETFASTINT (val, (intptr_t) connection);
1191 xd_registered_buses = Fcons (Fcons (bus, val), xd_registered_buses);
1192
1193 /* Cleanup. */
1194 dbus_error_free (&derror);
1195 }
1196
1197 /* Return reference counter. */
1198 refcount = xd_get_connection_references (connection);
1199 XD_DEBUG_MESSAGE ("Bus %s, Reference counter %"pD"d",
1200 XD_OBJECT_TO_STRING (bus), refcount);
1201 return make_number (refcount);
1202 }
1203
1204 DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name,
1205 1, 1, 0,
1206 doc: /* Return the unique name of Emacs registered at D-Bus BUS. */)
1207 (Lisp_Object bus)
1208 {
1209 DBusConnection *connection;
1210 const char *name;
1211
1212 /* Check parameter. */
1213 XD_DBUS_VALIDATE_BUS_ADDRESS (bus);
1214
1215 /* Retrieve bus address. */
1216 connection = xd_get_connection_address (bus);
1217
1218 /* Request the name. */
1219 name = dbus_bus_get_unique_name (connection);
1220 if (name == NULL)
1221 XD_SIGNAL1 (build_string ("No unique name available"));
1222
1223 /* Return. */
1224 return build_string (name);
1225 }
1226
1227 DEFUN ("dbus-message-internal", Fdbus_message_internal, Sdbus_message_internal,
1228 4, MANY, 0,
1229 doc: /* Send a D-Bus message.
1230 This is an internal function, it shall not be used outside dbus.el.
1231
1232 The following usages are expected:
1233
1234 `dbus-call-method', `dbus-call-method-asynchronously':
1235 (dbus-message-internal
1236 dbus-message-type-method-call BUS SERVICE PATH INTERFACE METHOD HANDLER
1237 &optional :timeout TIMEOUT &rest ARGS)
1238
1239 `dbus-send-signal':
1240 (dbus-message-internal
1241 dbus-message-type-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS)
1242
1243 `dbus-method-return-internal':
1244 (dbus-message-internal
1245 dbus-message-type-method-return BUS SERVICE SERIAL &rest ARGS)
1246
1247 `dbus-method-error-internal':
1248 (dbus-message-internal
1249 dbus-message-type-error BUS SERVICE SERIAL &rest ARGS)
1250
1251 usage: (dbus-message-internal &rest REST) */)
1252 (ptrdiff_t nargs, Lisp_Object *args)
1253 {
1254 Lisp_Object message_type, bus, service, handler;
1255 Lisp_Object path = Qnil;
1256 Lisp_Object interface = Qnil;
1257 Lisp_Object member = Qnil;
1258 Lisp_Object result;
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];
1269
1270 /* Initialize parameters. */
1271 message_type = args[0];
1272 bus = args[1];
1273 service = args[2];
1274 handler = Qnil;
1275
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);
1281
1282 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1283 || (mtype == DBUS_MESSAGE_TYPE_SIGNAL))
1284 {
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;
1291 }
1292 else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1293 {
1294 serial = xd_extract_unsigned (args[3], TYPE_MAXIMUM (dbus_uint32_t));
1295 count = 4;
1296 }
1297
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));
1305
1306 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1307 || (mtype == DBUS_MESSAGE_TYPE_SIGNAL))
1308 {
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);
1314 }
1315
1316 /* Trace parameters. */
1317 switch (mtype)
1318 {
1319 case DBUS_MESSAGE_TYPE_METHOD_CALL:
1320 XD_DEBUG_MESSAGE ("%s %s %s %s %s %s %s",
1321 XD_MESSAGE_TYPE_TO_STRING (mtype),
1322 XD_OBJECT_TO_STRING (bus),
1323 XD_OBJECT_TO_STRING (service),
1324 XD_OBJECT_TO_STRING (path),
1325 XD_OBJECT_TO_STRING (interface),
1326 XD_OBJECT_TO_STRING (member),
1327 XD_OBJECT_TO_STRING (handler));
1328 break;
1329 case DBUS_MESSAGE_TYPE_SIGNAL:
1330 XD_DEBUG_MESSAGE ("%s %s %s %s %s %s",
1331 XD_MESSAGE_TYPE_TO_STRING (mtype),
1332 XD_OBJECT_TO_STRING (bus),
1333 XD_OBJECT_TO_STRING (service),
1334 XD_OBJECT_TO_STRING (path),
1335 XD_OBJECT_TO_STRING (interface),
1336 XD_OBJECT_TO_STRING (member));
1337 break;
1338 default: /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1339 ui_serial = serial;
1340 XD_DEBUG_MESSAGE ("%s %s %s %u",
1341 XD_MESSAGE_TYPE_TO_STRING (mtype),
1342 XD_OBJECT_TO_STRING (bus),
1343 XD_OBJECT_TO_STRING (service),
1344 ui_serial);
1345 }
1346
1347 /* Retrieve bus address. */
1348 connection = xd_get_connection_address (bus);
1349
1350 /* Create the D-Bus message. */
1351 dmessage = dbus_message_new (mtype);
1352 if (dmessage == NULL)
1353 XD_SIGNAL1 (build_string ("Unable to create a new message"));
1354
1355 if (STRINGP (service))
1356 {
1357 if (mtype != DBUS_MESSAGE_TYPE_SIGNAL)
1358 /* Set destination. */
1359 {
1360 if (!dbus_message_set_destination (dmessage, SSDATA (service)))
1361 XD_SIGNAL2 (build_string ("Unable to set the destination"),
1362 service);
1363 }
1364
1365 else
1366 /* Set destination for unicast signals. */
1367 {
1368 Lisp_Object uname;
1369
1370 /* If it is the same unique name as we are registered at the
1371 bus or an unknown name, we regard it as broadcast message
1372 due to backward compatibility. */
1373 if (dbus_bus_name_has_owner (connection, SSDATA (service), NULL))
1374 uname = call2 (intern ("dbus-get-name-owner"), bus, service);
1375 else
1376 uname = Qnil;
1377
1378 if (STRINGP (uname)
1379 && (strcmp (dbus_bus_get_unique_name (connection), SSDATA (uname))
1380 != 0)
1381 && (!dbus_message_set_destination (dmessage, SSDATA (service))))
1382 XD_SIGNAL2 (build_string ("Unable to set signal destination"),
1383 service);
1384 }
1385 }
1386
1387 /* Set message parameters. */
1388 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1389 || (mtype == DBUS_MESSAGE_TYPE_SIGNAL))
1390 {
1391 if ((!dbus_message_set_path (dmessage, SSDATA (path)))
1392 || (!dbus_message_set_interface (dmessage, SSDATA (interface)))
1393 || (!dbus_message_set_member (dmessage, SSDATA (member))))
1394 XD_SIGNAL1 (build_string ("Unable to set the message parameter"));
1395 }
1396
1397 else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
1398 {
1399 if (!dbus_message_set_reply_serial (dmessage, serial))
1400 XD_SIGNAL1 (build_string ("Unable to create a return message"));
1401
1402 if ((mtype == DBUS_MESSAGE_TYPE_ERROR)
1403 && (!dbus_message_set_error_name (dmessage, DBUS_ERROR_FAILED)))
1404 XD_SIGNAL1 (build_string ("Unable to create a error message"));
1405 }
1406
1407 /* Check for timeout parameter. */
1408 if ((count+2 <= nargs) && (EQ ((args[count]), QCdbus_timeout)))
1409 {
1410 CHECK_NATNUM (args[count+1]);
1411 timeout = min (XFASTINT (args[count+1]), INT_MAX);
1412 count = count+2;
1413 }
1414
1415 /* Initialize parameter list of message. */
1416 dbus_message_iter_init_append (dmessage, &iter);
1417
1418 /* Append parameters to the message. */
1419 for (; count < nargs; ++count)
1420 {
1421 dtype = XD_OBJECT_TO_DBUS_TYPE (args[count]);
1422 if (XD_DBUS_TYPE_P (args[count]))
1423 {
1424 XD_DEBUG_VALID_LISP_OBJECT_P (args[count]);
1425 XD_DEBUG_VALID_LISP_OBJECT_P (args[count+1]);
1426 XD_DEBUG_MESSAGE ("Parameter%"pD"d %s %s", count - 4,
1427 XD_OBJECT_TO_STRING (args[count]),
1428 XD_OBJECT_TO_STRING (args[count+1]));
1429 ++count;
1430 }
1431 else
1432 {
1433 XD_DEBUG_VALID_LISP_OBJECT_P (args[count]);
1434 XD_DEBUG_MESSAGE ("Parameter%"pD"d %s", count - 4,
1435 XD_OBJECT_TO_STRING (args[count]));
1436 }
1437
1438 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1439 indication that there is no parent type. */
1440 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[count]);
1441
1442 xd_append_arg (dtype, args[count], &iter);
1443 }
1444
1445 if (!NILP (handler))
1446 {
1447 /* Send the message. The message is just added to the outgoing
1448 message queue. */
1449 if (!dbus_connection_send_with_reply (connection, dmessage,
1450 NULL, timeout))
1451 XD_SIGNAL1 (build_string ("Cannot send message"));
1452
1453 /* The result is the key in Vdbus_registered_objects_table. */
1454 serial = dbus_message_get_serial (dmessage);
1455 result = list3 (QCdbus_registered_serial,
1456 bus, make_fixnum_or_float (serial));
1457
1458 /* Create a hash table entry. */
1459 Fputhash (result, handler, Vdbus_registered_objects_table);
1460 }
1461 else
1462 {
1463 /* Send the message. The message is just added to the outgoing
1464 message queue. */
1465 if (!dbus_connection_send (connection, dmessage, NULL))
1466 XD_SIGNAL1 (build_string ("Cannot send message"));
1467
1468 result = Qnil;
1469 }
1470
1471 XD_DEBUG_MESSAGE ("Message sent: %s", XD_OBJECT_TO_STRING (result));
1472
1473 /* Cleanup. */
1474 dbus_message_unref (dmessage);
1475
1476 /* Return the result. */
1477 return result;
1478 }
1479
1480 /* Read one queued incoming message of the D-Bus BUS.
1481 BUS is either a Lisp symbol, :system or :session, or a string denoting
1482 the bus address. */
1483 static void
1484 xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
1485 {
1486 Lisp_Object args, key, value;
1487 struct input_event event;
1488 DBusMessage *dmessage;
1489 DBusMessageIter iter;
1490 int dtype;
1491 int mtype;
1492 dbus_uint32_t serial;
1493 unsigned int ui_serial;
1494 const char *uname, *path, *interface, *member;
1495
1496 dmessage = dbus_connection_pop_message (connection);
1497
1498 /* Return if there is no queued message. */
1499 if (dmessage == NULL)
1500 return;
1501
1502 /* Collect the parameters. */
1503 args = Qnil;
1504
1505 /* Loop over the resulting parameters. Construct a list. */
1506 if (dbus_message_iter_init (dmessage, &iter))
1507 {
1508 while ((dtype = dbus_message_iter_get_arg_type (&iter))
1509 != DBUS_TYPE_INVALID)
1510 {
1511 args = Fcons (xd_retrieve_arg (dtype, &iter), args);
1512 dbus_message_iter_next (&iter);
1513 }
1514 /* The arguments are stored in reverse order. Reorder them. */
1515 args = Fnreverse (args);
1516 }
1517
1518 /* Read message type, message serial, unique name, object path,
1519 interface and member from the message. */
1520 mtype = dbus_message_get_type (dmessage);
1521 ui_serial = serial =
1522 ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1523 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1524 ? dbus_message_get_reply_serial (dmessage)
1525 : dbus_message_get_serial (dmessage);
1526 uname = dbus_message_get_sender (dmessage);
1527 path = dbus_message_get_path (dmessage);
1528 interface = dbus_message_get_interface (dmessage);
1529 member = dbus_message_get_member (dmessage);
1530
1531 XD_DEBUG_MESSAGE ("Event received: %s %u %s %s %s %s %s",
1532 XD_MESSAGE_TYPE_TO_STRING (mtype),
1533 ui_serial, uname, path, interface, member,
1534 XD_OBJECT_TO_STRING (args));
1535
1536 if (mtype == DBUS_MESSAGE_TYPE_INVALID)
1537 goto cleanup;
1538
1539 else if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1540 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1541 {
1542 /* Search for a registered function of the message. */
1543 key = list3 (QCdbus_registered_serial, bus,
1544 make_fixnum_or_float (serial));
1545 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1546
1547 /* There shall be exactly one entry. Construct an event. */
1548 if (NILP (value))
1549 goto cleanup;
1550
1551 /* Remove the entry. */
1552 Fremhash (key, Vdbus_registered_objects_table);
1553
1554 /* Construct an event. */
1555 EVENT_INIT (event);
1556 event.kind = DBUS_EVENT;
1557 event.frame_or_window = Qnil;
1558 event.arg = Fcons (value, args);
1559 }
1560
1561 else /* DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_SIGNAL. */
1562 {
1563 /* Vdbus_registered_objects_table requires non-nil interface and
1564 member. */
1565 if ((interface == NULL) || (member == NULL))
1566 goto cleanup;
1567
1568 /* Search for a registered function of the message. */
1569 key = list4 ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1570 ? QCdbus_registered_method
1571 : QCdbus_registered_signal,
1572 bus, build_string (interface), build_string (member));
1573 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1574
1575 /* Loop over the registered functions. Construct an event. */
1576 while (!NILP (value))
1577 {
1578 key = CAR_SAFE (value);
1579 /* key has the structure (UNAME SERVICE PATH HANDLER). */
1580 if (((uname == NULL)
1581 || (NILP (CAR_SAFE (key)))
1582 || (strcmp (uname, SSDATA (CAR_SAFE (key))) == 0))
1583 && ((path == NULL)
1584 || (NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (key)))))
1585 || (strcmp (path,
1586 SSDATA (CAR_SAFE (CDR_SAFE (CDR_SAFE (key)))))
1587 == 0))
1588 && (!NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))))))
1589 {
1590 EVENT_INIT (event);
1591 event.kind = DBUS_EVENT;
1592 event.frame_or_window = Qnil;
1593 event.arg
1594 = Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))), args);
1595 break;
1596 }
1597 value = CDR_SAFE (value);
1598 }
1599
1600 if (NILP (value))
1601 goto cleanup;
1602 }
1603
1604 /* Add type, serial, uname, path, interface and member to the event. */
1605 event.arg = Fcons ((member == NULL ? Qnil : build_string (member)),
1606 event.arg);
1607 event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)),
1608 event.arg);
1609 event.arg = Fcons ((path == NULL ? Qnil : build_string (path)),
1610 event.arg);
1611 event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)),
1612 event.arg);
1613 event.arg = Fcons (make_fixnum_or_float (serial), event.arg);
1614 event.arg = Fcons (make_number (mtype), event.arg);
1615
1616 /* Add the bus symbol to the event. */
1617 event.arg = Fcons (bus, event.arg);
1618
1619 /* Store it into the input event queue. */
1620 kbd_buffer_store_event (&event);
1621
1622 XD_DEBUG_MESSAGE ("Event stored: %s", XD_OBJECT_TO_STRING (event.arg));
1623
1624 /* Cleanup. */
1625 cleanup:
1626 dbus_message_unref (dmessage);
1627 }
1628
1629 /* Read queued incoming messages of the D-Bus BUS.
1630 BUS is either a Lisp symbol, :system or :session, or a string denoting
1631 the bus address. */
1632 static Lisp_Object
1633 xd_read_message (Lisp_Object bus)
1634 {
1635 /* Retrieve bus address. */
1636 DBusConnection *connection = xd_get_connection_address (bus);
1637
1638 /* Non blocking read of the next available message. */
1639 dbus_connection_read_write (connection, 0);
1640
1641 while (dbus_connection_get_dispatch_status (connection)
1642 != DBUS_DISPATCH_COMPLETE)
1643 xd_read_message_1 (connection, bus);
1644 return Qnil;
1645 }
1646
1647 /* Callback called when something is ready to read or write. */
1648 static void
1649 xd_read_queued_messages (int fd, void *data)
1650 {
1651 Lisp_Object busp = xd_registered_buses;
1652 Lisp_Object bus = Qnil;
1653 Lisp_Object key;
1654
1655 /* Find bus related to fd. */
1656 if (data != NULL)
1657 while (!NILP (busp))
1658 {
1659 key = CAR_SAFE (CAR_SAFE (busp));
1660 if ((SYMBOLP (key) && XSYMBOL (key) == data)
1661 || (STRINGP (key) && XSTRING (key) == data))
1662 bus = key;
1663 busp = CDR_SAFE (busp);
1664 }
1665
1666 if (NILP (bus))
1667 return;
1668
1669 /* We ignore all Lisp errors during the call. */
1670 xd_in_read_queued_messages = 1;
1671 internal_catch (Qdbus_error, xd_read_message, bus);
1672 xd_in_read_queued_messages = 0;
1673 }
1674
1675 \f
1676 void
1677 init_dbusbind (void)
1678 {
1679 /* We do not want to abort. */
1680 xputenv ("DBUS_FATAL_WARNINGS=0");
1681 }
1682
1683 void
1684 syms_of_dbusbind (void)
1685 {
1686 defsubr (&Sdbus__init_bus);
1687 defsubr (&Sdbus_get_unique_name);
1688
1689 DEFSYM (Qdbus_message_internal, "dbus-message-internal");
1690 defsubr (&Sdbus_message_internal);
1691
1692 /* D-Bus error symbol. */
1693 DEFSYM (Qdbus_error, "dbus-error");
1694 Fput (Qdbus_error, Qerror_conditions,
1695 list2 (Qdbus_error, Qerror));
1696 Fput (Qdbus_error, Qerror_message,
1697 build_pure_c_string ("D-Bus error"));
1698
1699 /* Lisp symbols of the system and session buses. */
1700 DEFSYM (QCdbus_system_bus, ":system");
1701 DEFSYM (QCdbus_session_bus, ":session");
1702
1703 /* Lisp symbol for method call timeout. */
1704 DEFSYM (QCdbus_timeout, ":timeout");
1705
1706 /* Lisp symbols of D-Bus types. */
1707 DEFSYM (QCdbus_type_byte, ":byte");
1708 DEFSYM (QCdbus_type_boolean, ":boolean");
1709 DEFSYM (QCdbus_type_int16, ":int16");
1710 DEFSYM (QCdbus_type_uint16, ":uint16");
1711 DEFSYM (QCdbus_type_int32, ":int32");
1712 DEFSYM (QCdbus_type_uint32, ":uint32");
1713 DEFSYM (QCdbus_type_int64, ":int64");
1714 DEFSYM (QCdbus_type_uint64, ":uint64");
1715 DEFSYM (QCdbus_type_double, ":double");
1716 DEFSYM (QCdbus_type_string, ":string");
1717 DEFSYM (QCdbus_type_object_path, ":object-path");
1718 DEFSYM (QCdbus_type_signature, ":signature");
1719 #ifdef DBUS_TYPE_UNIX_FD
1720 DEFSYM (QCdbus_type_unix_fd, ":unix-fd");
1721 #endif
1722 DEFSYM (QCdbus_type_array, ":array");
1723 DEFSYM (QCdbus_type_variant, ":variant");
1724 DEFSYM (QCdbus_type_struct, ":struct");
1725 DEFSYM (QCdbus_type_dict_entry, ":dict-entry");
1726
1727 /* Lisp symbols of objects in `dbus-registered-objects-table'. */
1728 DEFSYM (QCdbus_registered_serial, ":serial");
1729 DEFSYM (QCdbus_registered_method, ":method");
1730 DEFSYM (QCdbus_registered_signal, ":signal");
1731
1732 DEFVAR_LISP ("dbus-compiled-version",
1733 Vdbus_compiled_version,
1734 doc: /* The version of D-Bus Emacs is compiled against. */);
1735 #ifdef DBUS_VERSION_STRING
1736 Vdbus_compiled_version = build_pure_c_string (DBUS_VERSION_STRING);
1737 #else
1738 Vdbus_compiled_version = Qnil;
1739 #endif
1740
1741 DEFVAR_LISP ("dbus-runtime-version",
1742 Vdbus_runtime_version,
1743 doc: /* The version of D-Bus Emacs runs with. */);
1744 {
1745 #ifdef DBUS_VERSION
1746 int major, minor, micro;
1747 char s[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
1748 dbus_get_version (&major, &minor, &micro);
1749 Vdbus_runtime_version
1750 = make_formatted_string (s, "%d.%d.%d", major, minor, micro);
1751 #else
1752 Vdbus_runtime_version = Qnil;
1753 #endif
1754 }
1755
1756 DEFVAR_LISP ("dbus-message-type-invalid",
1757 Vdbus_message_type_invalid,
1758 doc: /* This value is never a valid message type. */);
1759 Vdbus_message_type_invalid = make_number (DBUS_MESSAGE_TYPE_INVALID);
1760
1761 DEFVAR_LISP ("dbus-message-type-method-call",
1762 Vdbus_message_type_method_call,
1763 doc: /* Message type of a method call message. */);
1764 Vdbus_message_type_method_call = make_number (DBUS_MESSAGE_TYPE_METHOD_CALL);
1765
1766 DEFVAR_LISP ("dbus-message-type-method-return",
1767 Vdbus_message_type_method_return,
1768 doc: /* Message type of a method return message. */);
1769 Vdbus_message_type_method_return
1770 = make_number (DBUS_MESSAGE_TYPE_METHOD_RETURN);
1771
1772 DEFVAR_LISP ("dbus-message-type-error",
1773 Vdbus_message_type_error,
1774 doc: /* Message type of an error reply message. */);
1775 Vdbus_message_type_error = make_number (DBUS_MESSAGE_TYPE_ERROR);
1776
1777 DEFVAR_LISP ("dbus-message-type-signal",
1778 Vdbus_message_type_signal,
1779 doc: /* Message type of a signal message. */);
1780 Vdbus_message_type_signal = make_number (DBUS_MESSAGE_TYPE_SIGNAL);
1781
1782 DEFVAR_LISP ("dbus-registered-objects-table",
1783 Vdbus_registered_objects_table,
1784 doc: /* Hash table of registered functions for D-Bus.
1785
1786 There are two different uses of the hash table: for accessing
1787 registered interfaces properties, targeted by signals or method calls,
1788 and for calling handlers in case of non-blocking method call returns.
1789
1790 In the first case, the key in the hash table is the list (TYPE BUS
1791 INTERFACE MEMBER). TYPE is one of the Lisp symbols `:method',
1792 `:signal' or `:property'. BUS is either a Lisp symbol, `:system' or
1793 `:session', or a string denoting the bus address. INTERFACE is a
1794 string which denotes a D-Bus interface, and MEMBER, also a string, is
1795 either a method, a signal or a property INTERFACE is offering. All
1796 arguments but BUS must not be nil.
1797
1798 The value in the hash table is a list of quadruple lists ((UNAME
1799 SERVICE PATH OBJECT [RULE]) ...). SERVICE is the service name as
1800 registered, UNAME is the corresponding unique name. In case of
1801 registered methods and properties, UNAME is nil. PATH is the object
1802 path of the sending object. All of them can be nil, which means a
1803 wildcard then. OBJECT is either the handler to be called when a D-Bus
1804 message, which matches the key criteria, arrives (TYPE `:method' and
1805 `:signal'), or a cons cell containing the value of the property (TYPE
1806 `:property').
1807
1808 For entries of type `:signal', there is also a fifth element RULE,
1809 which keeps the match string the signal is registered with.
1810
1811 In the second case, the key in the hash table is the list (:serial BUS
1812 SERIAL). BUS is either a Lisp symbol, `:system' or `:session', or a
1813 string denoting the bus address. SERIAL is the serial number of the
1814 non-blocking method call, a reply is expected. Both arguments must
1815 not be nil. The value in the hash table is HANDLER, the function to
1816 be called when the D-Bus reply message arrives. */);
1817 Vdbus_registered_objects_table = CALLN (Fmake_hash_table, QCtest, Qequal);
1818
1819 DEFVAR_LISP ("dbus-debug", Vdbus_debug,
1820 doc: /* If non-nil, debug messages of D-Bus bindings are raised. */);
1821 #ifdef DBUS_DEBUG
1822 Vdbus_debug = Qt;
1823 /* We can also set environment variable DBUS_VERBOSE=1 in order to
1824 see more traces. This requires libdbus-1 to be configured with
1825 --enable-verbose-mode. */
1826 #else
1827 Vdbus_debug = Qnil;
1828 #endif
1829
1830 /* Initialize internal objects. */
1831 xd_registered_buses = Qnil;
1832 staticpro (&xd_registered_buses);
1833
1834 Fprovide (intern_c_string ("dbusbind"), Qnil);
1835
1836 }
1837
1838 #endif /* HAVE_DBUS */