* src/gmalloc.c: Remove BROKEN_PROTOTYPES reference, unused.
[bpt/emacs.git] / src / dbusbind.c
CommitLineData
033b73e2 1/* Elisp bindings for D-Bus.
114f9c96 2 Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
033b73e2
MA
3
4This file is part of GNU Emacs.
5
9ec0b715 6GNU Emacs is free software: you can redistribute it and/or modify
033b73e2 7it under the terms of the GNU General Public License as published by
9ec0b715
GM
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
033b73e2
MA
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
9ec0b715 17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
033b73e2
MA
18
19#include "config.h"
20
21#ifdef HAVE_DBUS
22#include <stdlib.h>
f5306ca3 23#include <stdio.h>
033b73e2 24#include <dbus/dbus.h>
d7306fe6 25#include <setjmp.h>
033b73e2
MA
26#include "lisp.h"
27#include "frame.h"
28#include "termhooks.h"
29#include "keyboard.h"
30
31\f
32/* Subroutines. */
058ed861 33Lisp_Object Qdbus_init_bus;
033b73e2
MA
34Lisp_Object Qdbus_get_unique_name;
35Lisp_Object Qdbus_call_method;
13ecc6dc 36Lisp_Object Qdbus_call_method_asynchronously;
8c7a4ac5 37Lisp_Object Qdbus_method_return_internal;
13ecc6dc 38Lisp_Object Qdbus_method_error_internal;
033b73e2
MA
39Lisp_Object Qdbus_send_signal;
40Lisp_Object Qdbus_register_signal;
17bc8f94 41Lisp_Object Qdbus_register_method;
033b73e2
MA
42
43/* D-Bus error symbol. */
44Lisp_Object Qdbus_error;
45
46/* Lisp symbols of the system and session buses. */
39abdd4a 47Lisp_Object QCdbus_system_bus, QCdbus_session_bus;
033b73e2 48
90b3fc84
MA
49/* Lisp symbol for method call timeout. */
50Lisp_Object QCdbus_timeout;
51
54371585
MA
52/* Lisp symbols of D-Bus types. */
53Lisp_Object QCdbus_type_byte, QCdbus_type_boolean;
54Lisp_Object QCdbus_type_int16, QCdbus_type_uint16;
55Lisp_Object QCdbus_type_int32, QCdbus_type_uint32;
56Lisp_Object QCdbus_type_int64, QCdbus_type_uint64;
57Lisp_Object QCdbus_type_double, QCdbus_type_string;
58Lisp_Object QCdbus_type_object_path, QCdbus_type_signature;
59Lisp_Object QCdbus_type_array, QCdbus_type_variant;
60Lisp_Object QCdbus_type_struct, QCdbus_type_dict_entry;
61
39abdd4a 62/* Hash table which keeps function definitions. */
f04bb9b2 63Lisp_Object Vdbus_registered_objects_table;
033b73e2
MA
64
65/* Whether to debug D-Bus. */
66Lisp_Object Vdbus_debug;
67
1dae9197
MA
68/* Whether we are reading a D-Bus event. */
69int xd_in_read_queued_messages = 0;
70
033b73e2
MA
71\f
72/* We use "xd_" and "XD_" as prefix for all internal symbols, because
73 we don't want to poison other namespaces with "dbus_". */
74
1dae9197
MA
75/* Raise a signal. If we are reading events, we cannot signal; we
76 throw to xd_read_queued_messages then. */
77#define XD_SIGNAL1(arg) \
78 do { \
79 if (xd_in_read_queued_messages) \
80 Fthrow (Qdbus_error, Qnil); \
81 else \
82 xsignal1 (Qdbus_error, arg); \
83 } while (0)
84
85#define XD_SIGNAL2(arg1, arg2) \
86 do { \
87 if (xd_in_read_queued_messages) \
88 Fthrow (Qdbus_error, Qnil); \
89 else \
90 xsignal2 (Qdbus_error, arg1, arg2); \
91 } while (0)
92
93#define XD_SIGNAL3(arg1, arg2, arg3) \
94 do { \
95 if (xd_in_read_queued_messages) \
96 Fthrow (Qdbus_error, Qnil); \
97 else \
98 xsignal3 (Qdbus_error, arg1, arg2, arg3); \
99 } while (0)
100
54371585 101/* Raise a Lisp error from a D-Bus ERROR. */
033b73e2 102#define XD_ERROR(error) \
17bc8f94 103 do { \
033b73e2 104 char s[1024]; \
4baa2377 105 strncpy (s, error.message, 1023); \
033b73e2
MA
106 dbus_error_free (&error); \
107 /* Remove the trailing newline. */ \
108 if (strchr (s, '\n') != NULL) \
109 s[strlen (s) - 1] = '\0'; \
1dae9197 110 XD_SIGNAL1 (build_string (s)); \
17bc8f94 111 } while (0)
033b73e2
MA
112
113/* Macros for debugging. In order to enable them, build with
17bc8f94 114 "make MYCPPFLAGS='-DDBUS_DEBUG -Wall'". */
033b73e2
MA
115#ifdef DBUS_DEBUG
116#define XD_DEBUG_MESSAGE(...) \
17bc8f94 117 do { \
033b73e2 118 char s[1024]; \
4baa2377 119 snprintf (s, 1023, __VA_ARGS__); \
033b73e2
MA
120 printf ("%s: %s\n", __func__, s); \
121 message ("%s: %s", __func__, s); \
17bc8f94 122 } while (0)
033b73e2 123#define XD_DEBUG_VALID_LISP_OBJECT_P(object) \
17bc8f94
MA
124 do { \
125 if (!valid_lisp_object_p (object)) \
126 { \
127 XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__); \
1dae9197 128 XD_SIGNAL1 (build_string ("Assertion failure")); \
17bc8f94
MA
129 } \
130 } while (0)
033b73e2
MA
131
132#else /* !DBUS_DEBUG */
17bc8f94
MA
133#define XD_DEBUG_MESSAGE(...) \
134 do { \
135 if (!NILP (Vdbus_debug)) \
136 { \
137 char s[1024]; \
4baa2377 138 snprintf (s, 1023, __VA_ARGS__); \
17bc8f94 139 message ("%s: %s", __func__, s); \
80f9d13b 140 } \
17bc8f94 141 } while (0)
033b73e2
MA
142#define XD_DEBUG_VALID_LISP_OBJECT_P(object)
143#endif
144
87cf1a39
MA
145/* Check whether TYPE is a basic DBusType. */
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
78c38319
MA
160/* This was a macro. On Solaris 2.11 it was said to compile for
161 hours, when optimzation is enabled. So we have transferred it into
162 a function. */
54371585
MA
163/* Determine the DBusType of a given Lisp symbol. OBJECT must be one
164 of the predefined D-Bus type symbols. */
78c38319
MA
165static int
166xd_symbol_to_dbus_type (object)
167 Lisp_Object object;
168{
169 return
170 ((EQ (object, QCdbus_type_byte)) ? DBUS_TYPE_BYTE
171 : (EQ (object, QCdbus_type_boolean)) ? DBUS_TYPE_BOOLEAN
172 : (EQ (object, QCdbus_type_int16)) ? DBUS_TYPE_INT16
173 : (EQ (object, QCdbus_type_uint16)) ? DBUS_TYPE_UINT16
174 : (EQ (object, QCdbus_type_int32)) ? DBUS_TYPE_INT32
175 : (EQ (object, QCdbus_type_uint32)) ? DBUS_TYPE_UINT32
176 : (EQ (object, QCdbus_type_int64)) ? DBUS_TYPE_INT64
177 : (EQ (object, QCdbus_type_uint64)) ? DBUS_TYPE_UINT64
178 : (EQ (object, QCdbus_type_double)) ? DBUS_TYPE_DOUBLE
179 : (EQ (object, QCdbus_type_string)) ? DBUS_TYPE_STRING
180 : (EQ (object, QCdbus_type_object_path)) ? DBUS_TYPE_OBJECT_PATH
181 : (EQ (object, QCdbus_type_signature)) ? DBUS_TYPE_SIGNATURE
182 : (EQ (object, QCdbus_type_array)) ? DBUS_TYPE_ARRAY
183 : (EQ (object, QCdbus_type_variant)) ? DBUS_TYPE_VARIANT
184 : (EQ (object, QCdbus_type_struct)) ? DBUS_TYPE_STRUCT
185 : (EQ (object, QCdbus_type_dict_entry)) ? DBUS_TYPE_DICT_ENTRY
186 : DBUS_TYPE_INVALID);
187}
87cf1a39
MA
188
189/* Check whether a Lisp symbol is a predefined D-Bus type symbol. */
190#define XD_DBUS_TYPE_P(object) \
78c38319 191 (SYMBOLP (object) && ((xd_symbol_to_dbus_type (object) != DBUS_TYPE_INVALID)))
54371585
MA
192
193/* Determine the DBusType of a given Lisp OBJECT. It is used to
033b73e2
MA
194 convert Lisp objects, being arguments of `dbus-call-method' or
195 `dbus-send-signal', into corresponding C values appended as
196 arguments to a D-Bus message. */
87cf1a39
MA
197#define XD_OBJECT_TO_DBUS_TYPE(object) \
198 ((EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN \
199 : (NATNUMP (object)) ? DBUS_TYPE_UINT32 \
200 : (INTEGERP (object)) ? DBUS_TYPE_INT32 \
201 : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \
202 : (STRINGP (object)) ? DBUS_TYPE_STRING \
78c38319 203 : (XD_DBUS_TYPE_P (object)) ? xd_symbol_to_dbus_type (object) \
07a4cb03
MA
204 : (CONSP (object)) \
205 ? ((XD_DBUS_TYPE_P (CAR_SAFE (object))) \
78c38319 206 ? ((XD_BASIC_DBUS_TYPE (xd_symbol_to_dbus_type (CAR_SAFE (object)))) \
07a4cb03 207 ? DBUS_TYPE_ARRAY \
78c38319 208 : xd_symbol_to_dbus_type (CAR_SAFE (object))) \
07a4cb03 209 : DBUS_TYPE_ARRAY) \
87cf1a39
MA
210 : DBUS_TYPE_INVALID)
211
212/* Return a list pointer which does not have a Lisp symbol as car. */
a8e72f4f 213#define XD_NEXT_VALUE(object) \
5125905e 214 ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object)
87cf1a39
MA
215
216/* Compute SIGNATURE of OBJECT. It must have a form that it can be
217 used in dbus_message_iter_open_container. DTYPE is the DBusType
218 the object is related to. It is passed as argument, because it
219 cannot be detected in basic type objects, when they are preceded by
220 a type symbol. PARENT_TYPE is the DBusType of a container this
221 signature is embedded, or DBUS_TYPE_INVALID. It is needed for the
222 check that DBUS_TYPE_DICT_ENTRY occurs only as array element. */
78c38319 223static void
4baa2377 224xd_signature (signature, dtype, parent_type, object)
87cf1a39
MA
225 char *signature;
226 unsigned int dtype, parent_type;
033b73e2
MA
227 Lisp_Object object;
228{
87cf1a39
MA
229 unsigned int subtype;
230 Lisp_Object elt;
231 char x[DBUS_MAXIMUM_SIGNATURE_LENGTH];
232
233 elt = object;
033b73e2 234
033b73e2
MA
235 switch (dtype)
236 {
54371585
MA
237 case DBUS_TYPE_BYTE:
238 case DBUS_TYPE_UINT16:
033b73e2 239 case DBUS_TYPE_UINT32:
54371585
MA
240 case DBUS_TYPE_UINT64:
241 CHECK_NATNUM (object);
87cf1a39 242 sprintf (signature, "%c", dtype);
54371585 243 break;
87cf1a39 244
54371585
MA
245 case DBUS_TYPE_BOOLEAN:
246 if (!EQ (object, Qt) && !EQ (object, Qnil))
247 wrong_type_argument (intern ("booleanp"), object);
87cf1a39 248 sprintf (signature, "%c", dtype);
54371585 249 break;
87cf1a39 250
54371585 251 case DBUS_TYPE_INT16:
033b73e2 252 case DBUS_TYPE_INT32:
54371585
MA
253 case DBUS_TYPE_INT64:
254 CHECK_NUMBER (object);
87cf1a39 255 sprintf (signature, "%c", dtype);
54371585 256 break;
87cf1a39 257
033b73e2 258 case DBUS_TYPE_DOUBLE:
54371585 259 CHECK_FLOAT (object);
87cf1a39 260 sprintf (signature, "%c", dtype);
54371585 261 break;
87cf1a39 262
033b73e2 263 case DBUS_TYPE_STRING:
54371585
MA
264 case DBUS_TYPE_OBJECT_PATH:
265 case DBUS_TYPE_SIGNATURE:
266 CHECK_STRING (object);
87cf1a39 267 sprintf (signature, "%c", dtype);
54371585 268 break;
87cf1a39 269
54371585 270 case DBUS_TYPE_ARRAY:
9af5078b 271 /* Check that all list elements have the same D-Bus type. For
87cf1a39
MA
272 complex element types, we just check the container type, not
273 the whole element's signature. */
54371585 274 CHECK_CONS (object);
87cf1a39 275
5125905e
MA
276 /* Type symbol is optional. */
277 if (EQ (QCdbus_type_array, CAR_SAFE (elt)))
87cf1a39 278 elt = XD_NEXT_VALUE (elt);
5125905e
MA
279
280 /* If the array is empty, DBUS_TYPE_STRING is the default
281 element type. */
282 if (NILP (elt))
283 {
284 subtype = DBUS_TYPE_STRING;
285 strcpy (x, DBUS_TYPE_STRING_AS_STRING);
286 }
287 else
288 {
289 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
290 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
291 }
292
293 /* If the element type is DBUS_TYPE_SIGNATURE, and this is the
294 only element, the value of this element is used as he array's
295 element signature. */
296 if ((subtype == DBUS_TYPE_SIGNATURE)
297 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt)))
298 && NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
299 strcpy (x, SDATA (CAR_SAFE (XD_NEXT_VALUE (elt))));
87cf1a39
MA
300
301 while (!NILP (elt))
302 {
5125905e
MA
303 if (subtype != XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)))
304 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (elt));
305 elt = CDR_SAFE (XD_NEXT_VALUE (elt));
87cf1a39
MA
306 }
307
308 sprintf (signature, "%c%s", dtype, x);
54371585 309 break;
87cf1a39 310
54371585 311 case DBUS_TYPE_VARIANT:
9af5078b 312 /* Check that there is exactly one list element. */
54371585 313 CHECK_CONS (object);
87cf1a39
MA
314
315 elt = XD_NEXT_VALUE (elt);
5125905e
MA
316 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
317 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
87cf1a39 318
5125905e 319 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
87cf1a39 320 wrong_type_argument (intern ("D-Bus"),
5125905e 321 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt))));
87cf1a39 322
a271e124 323 sprintf (signature, "%c", dtype);
54371585 324 break;
87cf1a39 325
54371585 326 case DBUS_TYPE_STRUCT:
9af5078b
MA
327 /* A struct list might contain any number of elements with
328 different types. No further check needed. */
87cf1a39
MA
329 CHECK_CONS (object);
330
331 elt = XD_NEXT_VALUE (elt);
332
333 /* Compose the signature from the elements. It is enclosed by
334 parentheses. */
335 sprintf (signature, "%c", DBUS_STRUCT_BEGIN_CHAR );
336 while (!NILP (elt))
337 {
5125905e
MA
338 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
339 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
87cf1a39 340 strcat (signature, x);
5125905e 341 elt = CDR_SAFE (XD_NEXT_VALUE (elt));
87cf1a39 342 }
0ef50993 343 strcat (signature, DBUS_STRUCT_END_CHAR_AS_STRING);
54371585 344 break;
54371585 345
87cf1a39 346 case DBUS_TYPE_DICT_ENTRY:
9af5078b
MA
347 /* Check that there are exactly two list elements, and the first
348 one is of basic type. The dictionary entry itself must be an
349 element of an array. */
87cf1a39 350 CHECK_CONS (object);
54371585 351
9af5078b 352 /* Check the parent object type. */
87cf1a39
MA
353 if (parent_type != DBUS_TYPE_ARRAY)
354 wrong_type_argument (intern ("D-Bus"), object);
54371585 355
87cf1a39
MA
356 /* Compose the signature from the elements. It is enclosed by
357 curly braces. */
358 sprintf (signature, "%c", DBUS_DICT_ENTRY_BEGIN_CHAR);
54371585 359
87cf1a39
MA
360 /* First element. */
361 elt = XD_NEXT_VALUE (elt);
5125905e
MA
362 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
363 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
87cf1a39 364 strcat (signature, x);
54371585 365
87cf1a39 366 if (!XD_BASIC_DBUS_TYPE (subtype))
5125905e 367 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt)));
54371585 368
87cf1a39 369 /* Second element. */
5125905e
MA
370 elt = CDR_SAFE (XD_NEXT_VALUE (elt));
371 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
372 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
87cf1a39 373 strcat (signature, x);
54371585 374
5125905e 375 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
87cf1a39 376 wrong_type_argument (intern ("D-Bus"),
5125905e 377 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt))));
54371585 378
87cf1a39 379 /* Closing signature. */
0ef50993 380 strcat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
87cf1a39 381 break;
54371585 382
87cf1a39
MA
383 default:
384 wrong_type_argument (intern ("D-Bus"), object);
54371585
MA
385 }
386
87cf1a39
MA
387 XD_DEBUG_MESSAGE ("%s", signature);
388}
54371585 389
87cf1a39
MA
390/* Append C value, extracted from Lisp OBJECT, to iteration ITER.
391 DTYPE must be a valid DBusType. It is used to convert Lisp
392 objects, being arguments of `dbus-call-method' or
393 `dbus-send-signal', into corresponding C values appended as
394 arguments to a D-Bus message. */
78c38319 395static void
87cf1a39
MA
396xd_append_arg (dtype, object, iter)
397 unsigned int dtype;
398 Lisp_Object object;
399 DBusMessageIter *iter;
400{
87cf1a39
MA
401 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
402 DBusMessageIter subiter;
87cf1a39
MA
403
404 if (XD_BASIC_DBUS_TYPE (dtype))
17bc8f94
MA
405 switch (dtype)
406 {
407 case DBUS_TYPE_BYTE:
54371585 408 {
8bba1b5c 409 unsigned char val = XUINT (object) & 0xFF;
17bc8f94
MA
410 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
411 if (!dbus_message_iter_append_basic (iter, dtype, &val))
1dae9197 412 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
17bc8f94
MA
413 return;
414 }
87cf1a39 415
17bc8f94
MA
416 case DBUS_TYPE_BOOLEAN:
417 {
418 dbus_bool_t val = (NILP (object)) ? FALSE : TRUE;
419 XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
420 if (!dbus_message_iter_append_basic (iter, dtype, &val))
1dae9197 421 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
17bc8f94
MA
422 return;
423 }
87cf1a39 424
17bc8f94
MA
425 case DBUS_TYPE_INT16:
426 {
427 dbus_int16_t val = XINT (object);
428 XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
429 if (!dbus_message_iter_append_basic (iter, dtype, &val))
1dae9197 430 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
17bc8f94
MA
431 return;
432 }
87cf1a39 433
17bc8f94
MA
434 case DBUS_TYPE_UINT16:
435 {
436 dbus_uint16_t val = XUINT (object);
437 XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val);
438 if (!dbus_message_iter_append_basic (iter, dtype, &val))
1dae9197 439 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
17bc8f94
MA
440 return;
441 }
87cf1a39 442
17bc8f94
MA
443 case DBUS_TYPE_INT32:
444 {
445 dbus_int32_t val = XINT (object);
446 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
447 if (!dbus_message_iter_append_basic (iter, dtype, &val))
1dae9197 448 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
17bc8f94
MA
449 return;
450 }
87cf1a39 451
17bc8f94
MA
452 case DBUS_TYPE_UINT32:
453 {
454 dbus_uint32_t val = XUINT (object);
455 XD_DEBUG_MESSAGE ("%c %u", dtype, val);
456 if (!dbus_message_iter_append_basic (iter, dtype, &val))
1dae9197 457 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
17bc8f94
MA
458 return;
459 }
87cf1a39 460
17bc8f94
MA
461 case DBUS_TYPE_INT64:
462 {
463 dbus_int64_t val = XINT (object);
464 XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
465 if (!dbus_message_iter_append_basic (iter, dtype, &val))
1dae9197 466 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
17bc8f94
MA
467 return;
468 }
87cf1a39 469
17bc8f94
MA
470 case DBUS_TYPE_UINT64:
471 {
472 dbus_uint64_t val = XUINT (object);
473 XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val);
474 if (!dbus_message_iter_append_basic (iter, dtype, &val))
1dae9197 475 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
17bc8f94 476 return;
54371585 477 }
87cf1a39 478
17bc8f94 479 case DBUS_TYPE_DOUBLE:
f601cdf3
KR
480 {
481 double val = XFLOAT_DATA (object);
482 XD_DEBUG_MESSAGE ("%c %f", dtype, val);
483 if (!dbus_message_iter_append_basic (iter, dtype, &val))
484 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
485 return;
486 }
17bc8f94
MA
487
488 case DBUS_TYPE_STRING:
489 case DBUS_TYPE_OBJECT_PATH:
490 case DBUS_TYPE_SIGNATURE:
491 {
4baa2377 492 char *val = SDATA (Fstring_make_unibyte (object));
17bc8f94
MA
493 XD_DEBUG_MESSAGE ("%c %s", dtype, val);
494 if (!dbus_message_iter_append_basic (iter, dtype, &val))
1dae9197 495 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
17bc8f94
MA
496 return;
497 }
498 }
87cf1a39
MA
499
500 else /* Compound types. */
501 {
502
503 /* All compound types except array have a type symbol. For
504 array, it is optional. Skip it. */
5125905e 505 if (!XD_BASIC_DBUS_TYPE (XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object))))
87cf1a39
MA
506 object = XD_NEXT_VALUE (object);
507
508 /* Open new subiteration. */
509 switch (dtype)
510 {
511 case DBUS_TYPE_ARRAY:
5125905e
MA
512 /* An array has only elements of the same type. So it is
513 sufficient to check the first element's signature
514 only. */
515
516 if (NILP (object))
517 /* If the array is empty, DBUS_TYPE_STRING is the default
518 element type. */
519 strcpy (signature, DBUS_TYPE_STRING_AS_STRING);
520
521 else
522 /* If the element type is DBUS_TYPE_SIGNATURE, and this is
523 the only element, the value of this element is used as
524 the array's element signature. */
525 if ((XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object))
526 == DBUS_TYPE_SIGNATURE)
527 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object)))
528 && NILP (CDR_SAFE (XD_NEXT_VALUE (object))))
529 {
530 strcpy (signature, SDATA (CAR_SAFE (XD_NEXT_VALUE (object))));
531 object = CDR_SAFE (XD_NEXT_VALUE (object));
532 }
533
534 else
535 xd_signature (signature,
536 XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)),
537 dtype, CAR_SAFE (XD_NEXT_VALUE (object)));
538
539 XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature,
540 SDATA (format2 ("%s", object, Qnil)));
541 if (!dbus_message_iter_open_container (iter, dtype,
542 signature, &subiter))
1dae9197
MA
543 XD_SIGNAL3 (build_string ("Cannot open container"),
544 make_number (dtype), build_string (signature));
5125905e
MA
545 break;
546
87cf1a39 547 case DBUS_TYPE_VARIANT:
5125905e
MA
548 /* A variant has just one element. */
549 xd_signature (signature, XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)),
550 dtype, CAR_SAFE (XD_NEXT_VALUE (object)));
551
87cf1a39
MA
552 XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature,
553 SDATA (format2 ("%s", object, Qnil)));
554 if (!dbus_message_iter_open_container (iter, dtype,
555 signature, &subiter))
1dae9197
MA
556 XD_SIGNAL3 (build_string ("Cannot open container"),
557 make_number (dtype), build_string (signature));
87cf1a39
MA
558 break;
559
560 case DBUS_TYPE_STRUCT:
561 case DBUS_TYPE_DICT_ENTRY:
9af5078b 562 /* These containers do not require a signature. */
87cf1a39
MA
563 XD_DEBUG_MESSAGE ("%c %s", dtype,
564 SDATA (format2 ("%s", object, Qnil)));
565 if (!dbus_message_iter_open_container (iter, dtype, NULL, &subiter))
1dae9197
MA
566 XD_SIGNAL2 (build_string ("Cannot open container"),
567 make_number (dtype));
87cf1a39
MA
568 break;
569 }
570
571 /* Loop over list elements. */
572 while (!NILP (object))
573 {
5125905e 574 dtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object));
87cf1a39
MA
575 object = XD_NEXT_VALUE (object);
576
5125905e 577 xd_append_arg (dtype, CAR_SAFE (object), &subiter);
87cf1a39 578
5125905e 579 object = CDR_SAFE (object);
87cf1a39
MA
580 }
581
9af5078b 582 /* Close the subiteration. */
87cf1a39 583 if (!dbus_message_iter_close_container (iter, &subiter))
1dae9197
MA
584 XD_SIGNAL2 (build_string ("Cannot close container"),
585 make_number (dtype));
87cf1a39 586 }
033b73e2
MA
587}
588
589/* Retrieve C value from a DBusMessageIter structure ITER, and return
590 a converted Lisp object. The type DTYPE of the argument of the
9af5078b
MA
591 D-Bus message must be a valid DBusType. Compound D-Bus types
592 result always in a Lisp list. */
78c38319 593static Lisp_Object
033b73e2 594xd_retrieve_arg (dtype, iter)
eb7c7bf5 595 unsigned int dtype;
033b73e2
MA
596 DBusMessageIter *iter;
597{
598
599 switch (dtype)
600 {
9af5078b 601 case DBUS_TYPE_BYTE:
9af5078b 602 {
17bc8f94 603 unsigned int val;
9af5078b 604 dbus_message_iter_get_basic (iter, &val);
17bc8f94 605 val = val & 0xFF;
9af5078b
MA
606 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
607 return make_number (val);
608 }
609
033b73e2
MA
610 case DBUS_TYPE_BOOLEAN:
611 {
612 dbus_bool_t val;
613 dbus_message_iter_get_basic (iter, &val);
87cf1a39 614 XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
033b73e2
MA
615 return (val == FALSE) ? Qnil : Qt;
616 }
87cf1a39 617
17bc8f94 618 case DBUS_TYPE_INT16:
1cae01f7
AS
619 {
620 dbus_int16_t val;
621 dbus_message_iter_get_basic (iter, &val);
622 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
623 return make_number (val);
624 }
625
17bc8f94
MA
626 case DBUS_TYPE_UINT16:
627 {
628 dbus_uint16_t val;
629 dbus_message_iter_get_basic (iter, &val);
630 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
631 return make_number (val);
632 }
633
033b73e2 634 case DBUS_TYPE_INT32:
1cae01f7
AS
635 {
636 dbus_int32_t val;
637 dbus_message_iter_get_basic (iter, &val);
638 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
639 return make_fixnum_or_float (val);
640 }
641
033b73e2
MA
642 case DBUS_TYPE_UINT32:
643 {
644 dbus_uint32_t val;
645 dbus_message_iter_get_basic (iter, &val);
17bc8f94 646 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
1cae01f7 647 return make_fixnum_or_float (val);
9af5078b
MA
648 }
649
650 case DBUS_TYPE_INT64:
1cae01f7
AS
651 {
652 dbus_int64_t val;
653 dbus_message_iter_get_basic (iter, &val);
654 XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
655 return make_fixnum_or_float (val);
656 }
657
9af5078b
MA
658 case DBUS_TYPE_UINT64:
659 {
660 dbus_uint64_t val;
661 dbus_message_iter_get_basic (iter, &val);
17bc8f94 662 XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
9af5078b
MA
663 return make_fixnum_or_float (val);
664 }
665
666 case DBUS_TYPE_DOUBLE:
667 {
668 double val;
669 dbus_message_iter_get_basic (iter, &val);
670 XD_DEBUG_MESSAGE ("%c %f", dtype, val);
671 return make_float (val);
033b73e2 672 }
87cf1a39 673
033b73e2
MA
674 case DBUS_TYPE_STRING:
675 case DBUS_TYPE_OBJECT_PATH:
9af5078b 676 case DBUS_TYPE_SIGNATURE:
033b73e2
MA
677 {
678 char *val;
679 dbus_message_iter_get_basic (iter, &val);
87cf1a39 680 XD_DEBUG_MESSAGE ("%c %s", dtype, val);
033b73e2
MA
681 return build_string (val);
682 }
87cf1a39 683
033b73e2
MA
684 case DBUS_TYPE_ARRAY:
685 case DBUS_TYPE_VARIANT:
686 case DBUS_TYPE_STRUCT:
687 case DBUS_TYPE_DICT_ENTRY:
688 {
689 Lisp_Object result;
690 struct gcpro gcpro1;
033b73e2
MA
691 DBusMessageIter subiter;
692 int subtype;
fa8e045a
MA
693 result = Qnil;
694 GCPRO1 (result);
033b73e2
MA
695 dbus_message_iter_recurse (iter, &subiter);
696 while ((subtype = dbus_message_iter_get_arg_type (&subiter))
697 != DBUS_TYPE_INVALID)
698 {
699 result = Fcons (xd_retrieve_arg (subtype, &subiter), result);
700 dbus_message_iter_next (&subiter);
701 }
5125905e 702 XD_DEBUG_MESSAGE ("%c %s", dtype, SDATA (format2 ("%s", result, Qnil)));
033b73e2
MA
703 RETURN_UNGCPRO (Fnreverse (result));
704 }
87cf1a39 705
033b73e2 706 default:
87cf1a39 707 XD_DEBUG_MESSAGE ("DBusType '%c' not supported", dtype);
033b73e2
MA
708 return Qnil;
709 }
710}
711
033b73e2
MA
712/* Initialize D-Bus connection. BUS is a Lisp symbol, either :system
713 or :session. It tells which D-Bus to be initialized. */
78c38319 714static DBusConnection *
033b73e2
MA
715xd_initialize (bus)
716 Lisp_Object bus;
717{
718 DBusConnection *connection;
719 DBusError derror;
720
721 /* Parameter check. */
722 CHECK_SYMBOL (bus);
3f56d3c6 723 if (!(EQ (bus, QCdbus_system_bus) || EQ (bus, QCdbus_session_bus)))
1dae9197 724 XD_SIGNAL2 (build_string ("Wrong bus name"), bus);
033b73e2 725
3f56d3c6
MA
726 /* We do not want to have an autolaunch for the session bus. */
727 if (EQ (bus, QCdbus_session_bus)
728 && getenv ("DBUS_SESSION_BUS_ADDRESS") == NULL)
729 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
730
033b73e2
MA
731 /* Open a connection to the bus. */
732 dbus_error_init (&derror);
733
39abdd4a 734 if (EQ (bus, QCdbus_system_bus))
033b73e2
MA
735 connection = dbus_bus_get (DBUS_BUS_SYSTEM, &derror);
736 else
737 connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
738
739 if (dbus_error_is_set (&derror))
740 XD_ERROR (derror);
741
742 if (connection == NULL)
3f56d3c6 743 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
033b73e2 744
c1d5ce94
MA
745 /* Cleanup. */
746 dbus_error_free (&derror);
747
033b73e2
MA
748 /* Return the result. */
749 return connection;
750}
751
058ed861
MA
752
753/* Add connection file descriptor to input_wait_mask, in order to
754 let select() detect, whether a new message has been arrived. */
755dbus_bool_t
756xd_add_watch (watch, data)
757 DBusWatch *watch;
758 void *data;
759{
760 /* We check only for incoming data. */
761 if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE)
762 {
eb4c6ace 763#if HAVE_DBUS_WATCH_GET_UNIX_FD
777013f2 764 /* TODO: Reverse these on Win32, which prefers the opposite. */
058ed861
MA
765 int fd = dbus_watch_get_unix_fd(watch);
766 if (fd == -1)
767 fd = dbus_watch_get_socket(watch);
3f56d3c6
MA
768#else
769 int fd = dbus_watch_get_fd(watch);
770#endif
777013f2 771 XD_DEBUG_MESSAGE ("fd %d", fd);
3f56d3c6 772
058ed861
MA
773 if (fd == -1)
774 return FALSE;
775
058ed861
MA
776 /* Add the file descriptor to input_wait_mask. */
777 add_keyboard_wait_descriptor (fd);
778 }
779
780 /* Return. */
781 return TRUE;
782}
783
777013f2
MA
784/* Remove connection file descriptor from input_wait_mask. DATA is
785 the used bus, either QCdbus_system_bus or QCdbus_session_bus. */
058ed861
MA
786void
787xd_remove_watch (watch, data)
788 DBusWatch *watch;
789 void *data;
790{
791 /* We check only for incoming data. */
792 if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE)
793 {
eb4c6ace 794#if HAVE_DBUS_WATCH_GET_UNIX_FD
777013f2 795 /* TODO: Reverse these on Win32, which prefers the opposite. */
058ed861
MA
796 int fd = dbus_watch_get_unix_fd(watch);
797 if (fd == -1)
798 fd = dbus_watch_get_socket(watch);
3f56d3c6
MA
799#else
800 int fd = dbus_watch_get_fd(watch);
801#endif
777013f2 802 XD_DEBUG_MESSAGE ("fd %d", fd);
3f56d3c6 803
058ed861
MA
804 if (fd == -1)
805 return;
806
777013f2 807 /* Unset session environment. */
e3eb1dae 808 if ((data != NULL) && (data == (void*) XHASH (QCdbus_session_bus)))
777013f2
MA
809 {
810 XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
811 unsetenv ("DBUS_SESSION_BUS_ADDRESS");
812 }
813
058ed861
MA
814 /* Remove the file descriptor from input_wait_mask. */
815 delete_keyboard_wait_descriptor (fd);
816 }
817
818 /* Return. */
819 return;
820}
821
822DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0,
823 doc: /* Initialize connection to D-Bus BUS.
824This is an internal function, it shall not be used outside dbus.el. */)
825 (bus)
826 Lisp_Object bus;
827{
828 DBusConnection *connection;
829
830 /* Check parameters. */
831 CHECK_SYMBOL (bus);
832
833 /* Open a connection to the bus. */
834 connection = xd_initialize (bus);
835
777013f2
MA
836 /* Add the watch functions. We pass also the bus as data, in order
837 to distinguish between the busses in xd_remove_watch. */
058ed861
MA
838 if (!dbus_connection_set_watch_functions (connection,
839 xd_add_watch,
840 xd_remove_watch,
e3eb1dae 841 NULL, (void*) XHASH (bus), NULL))
058ed861
MA
842 XD_SIGNAL1 (build_string ("Cannot add watch functions"));
843
844 /* Return. */
845 return Qnil;
846}
847
033b73e2
MA
848DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name,
849 1, 1, 0,
5125905e 850 doc: /* Return the unique name of Emacs registered at D-Bus BUS. */)
033b73e2
MA
851 (bus)
852 Lisp_Object bus;
853{
854 DBusConnection *connection;
48f7d213 855 const char *name;
033b73e2
MA
856
857 /* Check parameters. */
858 CHECK_SYMBOL (bus);
859
860 /* Open a connection to the bus. */
861 connection = xd_initialize (bus);
862
863 /* Request the name. */
48f7d213 864 name = dbus_bus_get_unique_name (connection);
033b73e2 865 if (name == NULL)
1dae9197 866 XD_SIGNAL1 (build_string ("No unique name available"));
033b73e2
MA
867
868 /* Return. */
869 return build_string (name);
870}
871
872DEFUN ("dbus-call-method", Fdbus_call_method, Sdbus_call_method, 5, MANY, 0,
873 doc: /* Call METHOD on the D-Bus BUS.
874
875BUS is either the symbol `:system' or the symbol `:session'.
876
877SERVICE is the D-Bus service name to be used. PATH is the D-Bus
878object path SERVICE is registered at. INTERFACE is an interface
879offered by SERVICE. It must provide METHOD.
880
90b3fc84 881If the parameter `:timeout' is given, the following integer TIMEOUT
f04bb9b2 882specifies the maximum number of milliseconds the method call must
1574224c 883return. The default value is 25,000. If the method call doesn't
48f7d213 884return in time, a D-Bus error is raised.
90b3fc84 885
033b73e2
MA
886All other arguments ARGS are passed to METHOD as arguments. They are
887converted into D-Bus types via the following rules:
888
889 t and nil => DBUS_TYPE_BOOLEAN
890 number => DBUS_TYPE_UINT32
891 integer => DBUS_TYPE_INT32
892 float => DBUS_TYPE_DOUBLE
893 string => DBUS_TYPE_STRING
87cf1a39 894 list => DBUS_TYPE_ARRAY
033b73e2 895
87cf1a39
MA
896All arguments can be preceded by a type symbol. For details about
897type symbols, see Info node `(dbus)Type Conversion'.
033b73e2
MA
898
899`dbus-call-method' returns the resulting values of METHOD as a list of
900Lisp objects. The type conversion happens the other direction as for
87cf1a39
MA
901input arguments. It follows the mapping rules:
902
903 DBUS_TYPE_BOOLEAN => t or nil
904 DBUS_TYPE_BYTE => number
905 DBUS_TYPE_UINT16 => number
906 DBUS_TYPE_INT16 => integer
9af5078b
MA
907 DBUS_TYPE_UINT32 => number or float
908 DBUS_TYPE_INT32 => integer or float
909 DBUS_TYPE_UINT64 => number or float
910 DBUS_TYPE_INT64 => integer or float
87cf1a39
MA
911 DBUS_TYPE_DOUBLE => float
912 DBUS_TYPE_STRING => string
913 DBUS_TYPE_OBJECT_PATH => string
914 DBUS_TYPE_SIGNATURE => string
915 DBUS_TYPE_ARRAY => list
916 DBUS_TYPE_VARIANT => list
917 DBUS_TYPE_STRUCT => list
918 DBUS_TYPE_DICT_ENTRY => list
919
920Example:
033b73e2
MA
921
922\(dbus-call-method
52da95fa
MA
923 :session "org.gnome.seahorse" "/org/gnome/seahorse/keys/openpgp"
924 "org.gnome.seahorse.Keys" "GetKeyField"
033b73e2
MA
925 "openpgp:657984B8C7A966DD" "simple-name")
926
927 => (t ("Philip R. Zimmermann"))
928
929If the result of the METHOD call is just one value, the converted Lisp
930object is returned instead of a list containing this single Lisp object.
931
932\(dbus-call-method
52da95fa
MA
933 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer"
934 "org.freedesktop.Hal.Device" "GetPropertyString"
033b73e2
MA
935 "system.kernel.machine")
936
937 => "i686"
938
edd9ab1e 939usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &optional :timeout TIMEOUT &rest ARGS) */)
033b73e2
MA
940 (nargs, args)
941 int nargs;
942 register Lisp_Object *args;
943{
52da95fa 944 Lisp_Object bus, service, path, interface, method;
033b73e2
MA
945 Lisp_Object result;
946 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
947 DBusConnection *connection;
948 DBusMessage *dmessage;
949 DBusMessage *reply;
950 DBusMessageIter iter;
951 DBusError derror;
eb7c7bf5 952 unsigned int dtype;
90b3fc84
MA
953 int timeout = -1;
954 int i = 5;
87cf1a39 955 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
033b73e2
MA
956
957 /* Check parameters. */
958 bus = args[0];
52da95fa
MA
959 service = args[1];
960 path = args[2];
961 interface = args[3];
962 method = args[4];
033b73e2
MA
963
964 CHECK_SYMBOL (bus);
033b73e2
MA
965 CHECK_STRING (service);
966 CHECK_STRING (path);
967 CHECK_STRING (interface);
52da95fa
MA
968 CHECK_STRING (method);
969 GCPRO5 (bus, service, path, interface, method);
033b73e2
MA
970
971 XD_DEBUG_MESSAGE ("%s %s %s %s",
033b73e2
MA
972 SDATA (service),
973 SDATA (path),
52da95fa
MA
974 SDATA (interface),
975 SDATA (method));
033b73e2
MA
976
977 /* Open a connection to the bus. */
978 connection = xd_initialize (bus);
979
980 /* Create the message. */
5125905e
MA
981 dmessage = dbus_message_new_method_call (SDATA (service),
982 SDATA (path),
983 SDATA (interface),
984 SDATA (method));
90b3fc84 985 UNGCPRO;
033b73e2 986 if (dmessage == NULL)
1dae9197 987 XD_SIGNAL1 (build_string ("Unable to create a new message"));
90b3fc84
MA
988
989 /* Check for timeout parameter. */
990 if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
033b73e2 991 {
90b3fc84
MA
992 CHECK_NATNUM (args[i+1]);
993 timeout = XUINT (args[i+1]);
994 i = i+2;
033b73e2
MA
995 }
996
54371585
MA
997 /* Initialize parameter list of message. */
998 dbus_message_iter_init_append (dmessage, &iter);
999
033b73e2 1000 /* Append parameters to the message. */
90b3fc84 1001 for (; i < nargs; ++i)
033b73e2 1002 {
87cf1a39
MA
1003 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1004 if (XD_DBUS_TYPE_P (args[i]))
8c7a4ac5
MA
1005 {
1006 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1007 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1008 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-4,
1009 SDATA (format2 ("%s", args[i], Qnil)),
1010 SDATA (format2 ("%s", args[i+1], Qnil)));
1011 ++i;
1012 }
1013 else
1014 {
1015 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1016 XD_DEBUG_MESSAGE ("Parameter%d %s", i-4,
1017 SDATA (format2 ("%s", args[i], Qnil)));
1018 }
033b73e2 1019
abe136ee 1020 /* Check for valid signature. We use DBUS_TYPE_INVALID as
87cf1a39
MA
1021 indication that there is no parent type. */
1022 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1023
54371585 1024 xd_append_arg (dtype, args[i], &iter);
033b73e2
MA
1025 }
1026
1027 /* Send the message. */
1028 dbus_error_init (&derror);
1029 reply = dbus_connection_send_with_reply_and_block (connection,
1030 dmessage,
90b3fc84 1031 timeout,
033b73e2
MA
1032 &derror);
1033
1034 if (dbus_error_is_set (&derror))
1035 XD_ERROR (derror);
1036
1037 if (reply == NULL)
1dae9197 1038 XD_SIGNAL1 (build_string ("No reply"));
033b73e2
MA
1039
1040 XD_DEBUG_MESSAGE ("Message sent");
1041
1042 /* Collect the results. */
1043 result = Qnil;
1044 GCPRO1 (result);
1045
2c3a8b27 1046 if (dbus_message_iter_init (reply, &iter))
033b73e2 1047 {
2c3a8b27
MH
1048 /* Loop over the parameters of the D-Bus reply message. Construct a
1049 Lisp list, which is returned by `dbus-call-method'. */
8c7a4ac5
MA
1050 while ((dtype = dbus_message_iter_get_arg_type (&iter))
1051 != DBUS_TYPE_INVALID)
2c3a8b27
MH
1052 {
1053 result = Fcons (xd_retrieve_arg (dtype, &iter), result);
1054 dbus_message_iter_next (&iter);
1055 }
033b73e2 1056 }
2c3a8b27 1057 else
033b73e2 1058 {
8c7a4ac5 1059 /* No arguments: just return nil. */
033b73e2
MA
1060 }
1061
1062 /* Cleanup. */
c1d5ce94 1063 dbus_error_free (&derror);
033b73e2
MA
1064 dbus_message_unref (dmessage);
1065 dbus_message_unref (reply);
1066
1067 /* Return the result. If there is only one single Lisp object,
1068 return it as-it-is, otherwise return the reversed list. */
1069 if (XUINT (Flength (result)) == 1)
5125905e 1070 RETURN_UNGCPRO (CAR_SAFE (result));
033b73e2
MA
1071 else
1072 RETURN_UNGCPRO (Fnreverse (result));
1073}
1074
13ecc6dc
MA
1075DEFUN ("dbus-call-method-asynchronously", Fdbus_call_method_asynchronously,
1076 Sdbus_call_method_asynchronously, 6, MANY, 0,
1077 doc: /* Call METHOD on the D-Bus BUS asynchronously.
1078
1079BUS is either the symbol `:system' or the symbol `:session'.
1080
1081SERVICE is the D-Bus service name to be used. PATH is the D-Bus
1082object path SERVICE is registered at. INTERFACE is an interface
1083offered by SERVICE. It must provide METHOD.
1084
1085HANDLER is a Lisp function, which is called when the corresponding
ca4f31ea
MA
1086return message has arrived. If HANDLER is nil, no return message will
1087be expected.
13ecc6dc
MA
1088
1089If the parameter `:timeout' is given, the following integer TIMEOUT
f04bb9b2 1090specifies the maximum number of milliseconds the method call must
1574224c 1091return. The default value is 25,000. If the method call doesn't
13ecc6dc
MA
1092return in time, a D-Bus error is raised.
1093
1094All other arguments ARGS are passed to METHOD as arguments. They are
1095converted into D-Bus types via the following rules:
1096
1097 t and nil => DBUS_TYPE_BOOLEAN
1098 number => DBUS_TYPE_UINT32
1099 integer => DBUS_TYPE_INT32
1100 float => DBUS_TYPE_DOUBLE
1101 string => DBUS_TYPE_STRING
1102 list => DBUS_TYPE_ARRAY
1103
1104All arguments can be preceded by a type symbol. For details about
1105type symbols, see Info node `(dbus)Type Conversion'.
1106
ca4f31ea 1107Unless HANDLER is nil, the function returns a key into the hash table
f04bb9b2
MA
1108`dbus-registered-objects-table'. The corresponding entry in the hash
1109table is removed, when the return message has been arrived, and
13ecc6dc
MA
1110HANDLER is called.
1111
1112Example:
1113
1114\(dbus-call-method-asynchronously
1115 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer"
1116 "org.freedesktop.Hal.Device" "GetPropertyString" 'message
1117 "system.kernel.machine")
1118
1119 => (:system 2)
1120
1121 -| i686
1122
edd9ab1e 1123usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLER &optional :timeout TIMEOUT &rest ARGS) */)
13ecc6dc
MA
1124 (nargs, args)
1125 int nargs;
1126 register Lisp_Object *args;
1127{
1128 Lisp_Object bus, service, path, interface, method, handler;
1129 Lisp_Object result;
1130 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
1131 DBusConnection *connection;
1132 DBusMessage *dmessage;
1133 DBusMessageIter iter;
1134 unsigned int dtype;
1135 int timeout = -1;
1136 int i = 6;
1137 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1138
1139 /* Check parameters. */
1140 bus = args[0];
1141 service = args[1];
1142 path = args[2];
1143 interface = args[3];
1144 method = args[4];
1145 handler = args[5];
1146
1147 CHECK_SYMBOL (bus);
1148 CHECK_STRING (service);
1149 CHECK_STRING (path);
1150 CHECK_STRING (interface);
1151 CHECK_STRING (method);
ca4f31ea 1152 if (!NILP (handler) && !FUNCTIONP (handler))
13ecc6dc
MA
1153 wrong_type_argument (intern ("functionp"), handler);
1154 GCPRO6 (bus, service, path, interface, method, handler);
1155
1156 XD_DEBUG_MESSAGE ("%s %s %s %s",
1157 SDATA (service),
1158 SDATA (path),
1159 SDATA (interface),
1160 SDATA (method));
1161
1162 /* Open a connection to the bus. */
1163 connection = xd_initialize (bus);
1164
1165 /* Create the message. */
1166 dmessage = dbus_message_new_method_call (SDATA (service),
1167 SDATA (path),
1168 SDATA (interface),
1169 SDATA (method));
1170 if (dmessage == NULL)
1dae9197 1171 XD_SIGNAL1 (build_string ("Unable to create a new message"));
13ecc6dc
MA
1172
1173 /* Check for timeout parameter. */
1174 if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
1175 {
1176 CHECK_NATNUM (args[i+1]);
1177 timeout = XUINT (args[i+1]);
1178 i = i+2;
1179 }
1180
1181 /* Initialize parameter list of message. */
1182 dbus_message_iter_init_append (dmessage, &iter);
1183
1184 /* Append parameters to the message. */
1185 for (; i < nargs; ++i)
1186 {
1187 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1188 if (XD_DBUS_TYPE_P (args[i]))
1189 {
1190 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1191 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1192 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-4,
1193 SDATA (format2 ("%s", args[i], Qnil)),
1194 SDATA (format2 ("%s", args[i+1], Qnil)));
1195 ++i;
1196 }
1197 else
1198 {
1199 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1200 XD_DEBUG_MESSAGE ("Parameter%d %s", i-4,
1201 SDATA (format2 ("%s", args[i], Qnil)));
1202 }
1203
1204 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1205 indication that there is no parent type. */
1206 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1207
1208 xd_append_arg (dtype, args[i], &iter);
1209 }
1210
ca4f31ea
MA
1211 if (!NILP (handler))
1212 {
1213 /* Send the message. The message is just added to the outgoing
1214 message queue. */
1215 if (!dbus_connection_send_with_reply (connection, dmessage,
1216 NULL, timeout))
1217 XD_SIGNAL1 (build_string ("Cannot send message"));
13ecc6dc 1218
f04bb9b2 1219 /* The result is the key in Vdbus_registered_objects_table. */
ca4f31ea 1220 result = (list2 (bus, make_number (dbus_message_get_serial (dmessage))));
13ecc6dc 1221
ca4f31ea 1222 /* Create a hash table entry. */
f04bb9b2 1223 Fputhash (result, handler, Vdbus_registered_objects_table);
ca4f31ea
MA
1224 }
1225 else
1226 {
1227 /* Send the message. The message is just added to the outgoing
1228 message queue. */
1229 if (!dbus_connection_send (connection, dmessage, NULL))
1230 XD_SIGNAL1 (build_string ("Cannot send message"));
13ecc6dc 1231
ca4f31ea
MA
1232 result = Qnil;
1233 }
1234
1235 /* Flush connection to ensure the message is handled. */
1236 dbus_connection_flush (connection);
1237
1238 XD_DEBUG_MESSAGE ("Message sent");
13ecc6dc
MA
1239
1240 /* Cleanup. */
1241 dbus_message_unref (dmessage);
1242
1243 /* Return the result. */
1244 RETURN_UNGCPRO (result);
1245}
1246
8c7a4ac5
MA
1247DEFUN ("dbus-method-return-internal", Fdbus_method_return_internal,
1248 Sdbus_method_return_internal,
abe136ee 1249 3, MANY, 0,
8c7a4ac5 1250 doc: /* Return for message SERIAL on the D-Bus BUS.
abe136ee
MA
1251This is an internal function, it shall not be used outside dbus.el.
1252
8c7a4ac5 1253usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */)
abe136ee
MA
1254 (nargs, args)
1255 int nargs;
1256 register Lisp_Object *args;
1257{
1258 Lisp_Object bus, serial, service;
1259 struct gcpro gcpro1, gcpro2, gcpro3;
1260 DBusConnection *connection;
1261 DBusMessage *dmessage;
1262 DBusMessageIter iter;
1263 unsigned int dtype;
1264 int i;
1265 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1266
1267 /* Check parameters. */
1268 bus = args[0];
1269 serial = args[1];
1270 service = args[2];
1271
1272 CHECK_SYMBOL (bus);
1273 CHECK_NUMBER (serial);
1274 CHECK_STRING (service);
1275 GCPRO3 (bus, serial, service);
1276
603f0bf0 1277 XD_DEBUG_MESSAGE ("%lu %s ", (unsigned long) XUINT (serial), SDATA (service));
abe136ee
MA
1278
1279 /* Open a connection to the bus. */
1280 connection = xd_initialize (bus);
1281
1282 /* Create the message. */
1283 dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
1284 if ((dmessage == NULL)
1285 || (!dbus_message_set_reply_serial (dmessage, XUINT (serial)))
1286 || (!dbus_message_set_destination (dmessage, SDATA (service))))
1287 {
1288 UNGCPRO;
1dae9197 1289 XD_SIGNAL1 (build_string ("Unable to create a return message"));
abe136ee
MA
1290 }
1291
1292 UNGCPRO;
1293
1294 /* Initialize parameter list of message. */
1295 dbus_message_iter_init_append (dmessage, &iter);
1296
1297 /* Append parameters to the message. */
1298 for (i = 3; i < nargs; ++i)
1299 {
abe136ee
MA
1300 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1301 if (XD_DBUS_TYPE_P (args[i]))
8c7a4ac5
MA
1302 {
1303 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1304 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1305 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-2,
1306 SDATA (format2 ("%s", args[i], Qnil)),
1307 SDATA (format2 ("%s", args[i+1], Qnil)));
1308 ++i;
1309 }
1310 else
1311 {
1312 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1313 XD_DEBUG_MESSAGE ("Parameter%d %s", i-2,
1314 SDATA (format2 ("%s", args[i], Qnil)));
1315 }
abe136ee
MA
1316
1317 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1318 indication that there is no parent type. */
1319 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1320
1321 xd_append_arg (dtype, args[i], &iter);
1322 }
1323
1324 /* Send the message. The message is just added to the outgoing
1325 message queue. */
1326 if (!dbus_connection_send (connection, dmessage, NULL))
1dae9197 1327 XD_SIGNAL1 (build_string ("Cannot send message"));
abe136ee
MA
1328
1329 /* Flush connection to ensure the message is handled. */
1330 dbus_connection_flush (connection);
1331
1332 XD_DEBUG_MESSAGE ("Message sent");
1333
1334 /* Cleanup. */
1335 dbus_message_unref (dmessage);
1336
1337 /* Return. */
1338 return Qt;
1339}
1340
13ecc6dc
MA
1341DEFUN ("dbus-method-error-internal", Fdbus_method_error_internal,
1342 Sdbus_method_error_internal,
1343 3, MANY, 0,
1344 doc: /* Return error message for message SERIAL on the D-Bus BUS.
1345This is an internal function, it shall not be used outside dbus.el.
1346
1347usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */)
1348 (nargs, args)
1349 int nargs;
1350 register Lisp_Object *args;
1351{
1352 Lisp_Object bus, serial, service;
1353 struct gcpro gcpro1, gcpro2, gcpro3;
1354 DBusConnection *connection;
1355 DBusMessage *dmessage;
1356 DBusMessageIter iter;
1357 unsigned int dtype;
1358 int i;
1359 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1360
1361 /* Check parameters. */
1362 bus = args[0];
1363 serial = args[1];
1364 service = args[2];
1365
1366 CHECK_SYMBOL (bus);
1367 CHECK_NUMBER (serial);
1368 CHECK_STRING (service);
1369 GCPRO3 (bus, serial, service);
1370
603f0bf0 1371 XD_DEBUG_MESSAGE ("%lu %s ", (unsigned long) XUINT (serial), SDATA (service));
13ecc6dc
MA
1372
1373 /* Open a connection to the bus. */
1374 connection = xd_initialize (bus);
1375
1376 /* Create the message. */
1377 dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
1378 if ((dmessage == NULL)
1379 || (!dbus_message_set_error_name (dmessage, DBUS_ERROR_FAILED))
1380 || (!dbus_message_set_reply_serial (dmessage, XUINT (serial)))
1381 || (!dbus_message_set_destination (dmessage, SDATA (service))))
1382 {
1383 UNGCPRO;
1dae9197 1384 XD_SIGNAL1 (build_string ("Unable to create a error message"));
13ecc6dc
MA
1385 }
1386
1387 UNGCPRO;
1388
1389 /* Initialize parameter list of message. */
1390 dbus_message_iter_init_append (dmessage, &iter);
1391
1392 /* Append parameters to the message. */
1393 for (i = 3; i < nargs; ++i)
1394 {
1395 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1396 if (XD_DBUS_TYPE_P (args[i]))
1397 {
1398 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1399 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1400 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-2,
1401 SDATA (format2 ("%s", args[i], Qnil)),
1402 SDATA (format2 ("%s", args[i+1], Qnil)));
1403 ++i;
1404 }
1405 else
1406 {
1407 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1408 XD_DEBUG_MESSAGE ("Parameter%d %s", i-2,
1409 SDATA (format2 ("%s", args[i], Qnil)));
1410 }
1411
1412 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1413 indication that there is no parent type. */
1414 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1415
1416 xd_append_arg (dtype, args[i], &iter);
1417 }
1418
1419 /* Send the message. The message is just added to the outgoing
1420 message queue. */
1421 if (!dbus_connection_send (connection, dmessage, NULL))
1dae9197 1422 XD_SIGNAL1 (build_string ("Cannot send message"));
13ecc6dc
MA
1423
1424 /* Flush connection to ensure the message is handled. */
1425 dbus_connection_flush (connection);
1426
1427 XD_DEBUG_MESSAGE ("Message sent");
1428
1429 /* Cleanup. */
1430 dbus_message_unref (dmessage);
1431
1432 /* Return. */
1433 return Qt;
1434}
1435
033b73e2
MA
1436DEFUN ("dbus-send-signal", Fdbus_send_signal, Sdbus_send_signal, 5, MANY, 0,
1437 doc: /* Send signal SIGNAL on the D-Bus BUS.
1438
1439BUS is either the symbol `:system' or the symbol `:session'.
1440
1441SERVICE is the D-Bus service name SIGNAL is sent from. PATH is the
1442D-Bus object path SERVICE is registered at. INTERFACE is an interface
1443offered by SERVICE. It must provide signal SIGNAL.
1444
1445All other arguments ARGS are passed to SIGNAL as arguments. They are
1446converted into D-Bus types via the following rules:
1447
1448 t and nil => DBUS_TYPE_BOOLEAN
1449 number => DBUS_TYPE_UINT32
1450 integer => DBUS_TYPE_INT32
1451 float => DBUS_TYPE_DOUBLE
1452 string => DBUS_TYPE_STRING
87cf1a39 1453 list => DBUS_TYPE_ARRAY
033b73e2 1454
87cf1a39
MA
1455All arguments can be preceded by a type symbol. For details about
1456type symbols, see Info node `(dbus)Type Conversion'.
033b73e2
MA
1457
1458Example:
1459
1460\(dbus-send-signal
52da95fa
MA
1461 :session "org.gnu.Emacs" "/org/gnu/Emacs"
1462 "org.gnu.Emacs.FileManager" "FileModified" "/home/albinus/.emacs")
033b73e2 1463
52da95fa 1464usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
033b73e2
MA
1465 (nargs, args)
1466 int nargs;
1467 register Lisp_Object *args;
1468{
52da95fa 1469 Lisp_Object bus, service, path, interface, signal;
033b73e2
MA
1470 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
1471 DBusConnection *connection;
1472 DBusMessage *dmessage;
54371585 1473 DBusMessageIter iter;
eb7c7bf5 1474 unsigned int dtype;
033b73e2 1475 int i;
87cf1a39 1476 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
033b73e2
MA
1477
1478 /* Check parameters. */
1479 bus = args[0];
52da95fa
MA
1480 service = args[1];
1481 path = args[2];
1482 interface = args[3];
1483 signal = args[4];
033b73e2
MA
1484
1485 CHECK_SYMBOL (bus);
033b73e2
MA
1486 CHECK_STRING (service);
1487 CHECK_STRING (path);
1488 CHECK_STRING (interface);
52da95fa
MA
1489 CHECK_STRING (signal);
1490 GCPRO5 (bus, service, path, interface, signal);
033b73e2
MA
1491
1492 XD_DEBUG_MESSAGE ("%s %s %s %s",
033b73e2
MA
1493 SDATA (service),
1494 SDATA (path),
52da95fa
MA
1495 SDATA (interface),
1496 SDATA (signal));
033b73e2
MA
1497
1498 /* Open a connection to the bus. */
1499 connection = xd_initialize (bus);
1500
1501 /* Create the message. */
5125905e
MA
1502 dmessage = dbus_message_new_signal (SDATA (path),
1503 SDATA (interface),
1504 SDATA (signal));
033b73e2 1505 UNGCPRO;
90b3fc84 1506 if (dmessage == NULL)
1dae9197 1507 XD_SIGNAL1 (build_string ("Unable to create a new message"));
033b73e2 1508
54371585
MA
1509 /* Initialize parameter list of message. */
1510 dbus_message_iter_init_append (dmessage, &iter);
1511
033b73e2
MA
1512 /* Append parameters to the message. */
1513 for (i = 5; i < nargs; ++i)
1514 {
87cf1a39
MA
1515 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1516 if (XD_DBUS_TYPE_P (args[i]))
8c7a4ac5
MA
1517 {
1518 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1519 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1520 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-4,
1521 SDATA (format2 ("%s", args[i], Qnil)),
1522 SDATA (format2 ("%s", args[i+1], Qnil)));
1523 ++i;
1524 }
1525 else
1526 {
1527 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1528 XD_DEBUG_MESSAGE ("Parameter%d %s", i-4,
1529 SDATA (format2 ("%s", args[i], Qnil)));
1530 }
033b73e2 1531
abe136ee 1532 /* Check for valid signature. We use DBUS_TYPE_INVALID as
87cf1a39
MA
1533 indication that there is no parent type. */
1534 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1535
54371585 1536 xd_append_arg (dtype, args[i], &iter);
033b73e2
MA
1537 }
1538
1539 /* Send the message. The message is just added to the outgoing
1540 message queue. */
1541 if (!dbus_connection_send (connection, dmessage, NULL))
1dae9197 1542 XD_SIGNAL1 (build_string ("Cannot send message"));
033b73e2
MA
1543
1544 /* Flush connection to ensure the message is handled. */
1545 dbus_connection_flush (connection);
1546
1547 XD_DEBUG_MESSAGE ("Signal sent");
1548
1549 /* Cleanup. */
1550 dbus_message_unref (dmessage);
1551
1552 /* Return. */
1553 return Qt;
1554}
1555
f573d588
MA
1556/* Check, whether there is pending input in the message queue of the
1557 D-Bus BUS. BUS is a Lisp symbol, either :system or :session. */
1558int
1559xd_get_dispatch_status (bus)
1560 Lisp_Object bus;
1561{
1562 DBusConnection *connection;
1563
1564 /* Open a connection to the bus. */
1565 connection = xd_initialize (bus);
1566
1567 /* Non blocking read of the next available message. */
1568 dbus_connection_read_write (connection, 0);
1569
1570 /* Return. */
1571 return
1572 (dbus_connection_get_dispatch_status (connection)
1573 == DBUS_DISPATCH_DATA_REMAINS)
1574 ? TRUE : FALSE;
1575}
1576
1577/* Check for queued incoming messages from the system and session buses. */
1578int
1579xd_pending_messages ()
1580{
1581
f04bb9b2
MA
1582 /* Vdbus_registered_objects_table will be initialized as hash table
1583 in dbus.el. When this package isn't loaded yet, it doesn't make
1584 sense to handle D-Bus messages. */
1585 return (HASH_TABLE_P (Vdbus_registered_objects_table)
3f56d3c6
MA
1586 ? (xd_get_dispatch_status (QCdbus_system_bus)
1587 || ((getenv ("DBUS_SESSION_BUS_ADDRESS") != NULL)
1588 ? xd_get_dispatch_status (QCdbus_session_bus)
1589 : FALSE))
f573d588
MA
1590 : FALSE);
1591}
1592
033b73e2
MA
1593/* Read queued incoming message of the D-Bus BUS. BUS is a Lisp
1594 symbol, either :system or :session. */
78c38319 1595static Lisp_Object
033b73e2
MA
1596xd_read_message (bus)
1597 Lisp_Object bus;
1598{
a31d47c7 1599 Lisp_Object args, key, value;
033b73e2 1600 struct gcpro gcpro1;
15f16c1b 1601 struct input_event event;
033b73e2
MA
1602 DBusConnection *connection;
1603 DBusMessage *dmessage;
1604 DBusMessageIter iter;
eb7c7bf5 1605 unsigned int dtype;
13ecc6dc 1606 int mtype, serial;
a8e72f4f 1607 const char *uname, *path, *interface, *member;
39abdd4a 1608
033b73e2
MA
1609 /* Open a connection to the bus. */
1610 connection = xd_initialize (bus);
1611
1612 /* Non blocking read of the next available message. */
1613 dbus_connection_read_write (connection, 0);
1614 dmessage = dbus_connection_pop_message (connection);
1615
1616 /* Return if there is no queued message. */
1617 if (dmessage == NULL)
17bc8f94 1618 return Qnil;
033b73e2
MA
1619
1620 /* Collect the parameters. */
a31d47c7
MA
1621 args = Qnil;
1622 GCPRO1 (args);
033b73e2 1623
033b73e2 1624 /* Loop over the resulting parameters. Construct a list. */
17bc8f94 1625 if (dbus_message_iter_init (dmessage, &iter))
033b73e2 1626 {
17bc8f94
MA
1627 while ((dtype = dbus_message_iter_get_arg_type (&iter))
1628 != DBUS_TYPE_INVALID)
1629 {
1630 args = Fcons (xd_retrieve_arg (dtype, &iter), args);
1631 dbus_message_iter_next (&iter);
1632 }
1633 /* The arguments are stored in reverse order. Reorder them. */
1634 args = Fnreverse (args);
033b73e2
MA
1635 }
1636
13ecc6dc
MA
1637 /* Read message type, message serial, unique name, object path,
1638 interface and member from the message. */
367ea173
MA
1639 mtype = dbus_message_get_type (dmessage);
1640 serial =
1641 ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1642 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1643 ? dbus_message_get_reply_serial (dmessage)
1644 : dbus_message_get_serial (dmessage);
1645 uname = dbus_message_get_sender (dmessage);
1646 path = dbus_message_get_path (dmessage);
a8e72f4f 1647 interface = dbus_message_get_interface (dmessage);
367ea173 1648 member = dbus_message_get_member (dmessage);
a8e72f4f 1649
13ecc6dc 1650 XD_DEBUG_MESSAGE ("Event received: %s %d %s %s %s %s %s",
367ea173
MA
1651 (mtype == DBUS_MESSAGE_TYPE_INVALID)
1652 ? "DBUS_MESSAGE_TYPE_INVALID"
1653 : (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1654 ? "DBUS_MESSAGE_TYPE_METHOD_CALL"
1655 : (mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1656 ? "DBUS_MESSAGE_TYPE_METHOD_RETURN"
1657 : (mtype == DBUS_MESSAGE_TYPE_ERROR)
1658 ? "DBUS_MESSAGE_TYPE_ERROR"
1659 : "DBUS_MESSAGE_TYPE_SIGNAL",
13ecc6dc 1660 serial, uname, path, interface, member,
17bc8f94
MA
1661 SDATA (format2 ("%s", args, Qnil)));
1662
367ea173
MA
1663 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1664 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
13ecc6dc
MA
1665 {
1666 /* Search for a registered function of the message. */
1667 key = list2 (bus, make_number (serial));
f04bb9b2 1668 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
13ecc6dc
MA
1669
1670 /* There shall be exactly one entry. Construct an event. */
1671 if (NILP (value))
1672 goto cleanup;
1673
1674 /* Remove the entry. */
f04bb9b2 1675 Fremhash (key, Vdbus_registered_objects_table);
13ecc6dc
MA
1676
1677 /* Construct an event. */
1678 EVENT_INIT (event);
1679 event.kind = DBUS_EVENT;
1680 event.frame_or_window = Qnil;
1681 event.arg = Fcons (value, args);
1682 }
a31d47c7 1683
13ecc6dc 1684 else /* (mtype != DBUS_MESSAGE_TYPE_METHOD_RETURN) */
a31d47c7 1685 {
f04bb9b2
MA
1686 /* Vdbus_registered_objects_table requires non-nil interface and
1687 member. */
13ecc6dc
MA
1688 if ((interface == NULL) || (member == NULL))
1689 goto cleanup;
1690
1691 /* Search for a registered function of the message. */
1692 key = list3 (bus, build_string (interface), build_string (member));
f04bb9b2 1693 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
13ecc6dc
MA
1694
1695 /* Loop over the registered functions. Construct an event. */
1696 while (!NILP (value))
a31d47c7 1697 {
13ecc6dc
MA
1698 key = CAR_SAFE (value);
1699 /* key has the structure (UNAME SERVICE PATH HANDLER). */
1700 if (((uname == NULL)
1701 || (NILP (CAR_SAFE (key)))
1702 || (strcmp (uname, SDATA (CAR_SAFE (key))) == 0))
1703 && ((path == NULL)
1704 || (NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (key)))))
1705 || (strcmp (path,
1706 SDATA (CAR_SAFE (CDR_SAFE (CDR_SAFE (key)))))
1707 == 0))
1708 && (!NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))))))
1709 {
1710 EVENT_INIT (event);
1711 event.kind = DBUS_EVENT;
1712 event.frame_or_window = Qnil;
1713 event.arg = Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))),
1714 args);
1715 break;
1716 }
1717 value = CDR_SAFE (value);
a31d47c7 1718 }
13ecc6dc
MA
1719
1720 if (NILP (value))
1721 goto cleanup;
a31d47c7 1722 }
033b73e2 1723
13ecc6dc
MA
1724 /* Add type, serial, uname, path, interface and member to the event. */
1725 event.arg = Fcons ((member == NULL ? Qnil : build_string (member)),
1726 event.arg);
1727 event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)),
1728 event.arg);
1729 event.arg = Fcons ((path == NULL ? Qnil : build_string (path)),
1730 event.arg);
1731 event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)),
1732 event.arg);
1733 event.arg = Fcons (make_number (serial), event.arg);
1734 event.arg = Fcons (make_number (mtype), event.arg);
1735
1736 /* Add the bus symbol to the event. */
1737 event.arg = Fcons (bus, event.arg);
1738
1739 /* Store it into the input event queue. */
1740 kbd_buffer_store_event (&event);
1741
1742 XD_DEBUG_MESSAGE ("Event stored: %s",
1743 SDATA (format2 ("%s", event.arg, Qnil)));
1744
c1d5ce94 1745 /* Cleanup. */
a8e72f4f 1746 cleanup:
033b73e2 1747 dbus_message_unref (dmessage);
c1d5ce94 1748
17bc8f94 1749 RETURN_UNGCPRO (Qnil);
033b73e2
MA
1750}
1751
1752/* Read queued incoming messages from the system and session buses. */
1753void
1754xd_read_queued_messages ()
1755{
96faeb40 1756
f04bb9b2
MA
1757 /* Vdbus_registered_objects_table will be initialized as hash table
1758 in dbus.el. When this package isn't loaded yet, it doesn't make
1759 sense to handle D-Bus messages. Furthermore, we ignore all Lisp
1760 errors during the call. */
1761 if (HASH_TABLE_P (Vdbus_registered_objects_table))
96faeb40 1762 {
1dae9197
MA
1763 xd_in_read_queued_messages = 1;
1764 internal_catch (Qdbus_error, xd_read_message, QCdbus_system_bus);
1765 internal_catch (Qdbus_error, xd_read_message, QCdbus_session_bus);
1766 xd_in_read_queued_messages = 0;
96faeb40 1767 }
033b73e2
MA
1768}
1769
1770DEFUN ("dbus-register-signal", Fdbus_register_signal, Sdbus_register_signal,
944cc4a8 1771 6, MANY, 0,
033b73e2
MA
1772 doc: /* Register for signal SIGNAL on the D-Bus BUS.
1773
1774BUS is either the symbol `:system' or the symbol `:session'.
1775
39abdd4a
MA
1776SERVICE is the D-Bus service name used by the sending D-Bus object.
1777It can be either a known name or the unique name of the D-Bus object
1778sending the signal. When SERVICE is nil, related signals from all
1779D-Bus objects shall be accepted.
033b73e2 1780
39abdd4a
MA
1781PATH is the D-Bus object path SERVICE is registered. It can also be
1782nil if the path name of incoming signals shall not be checked.
033b73e2 1783
39abdd4a
MA
1784INTERFACE is an interface offered by SERVICE. It must provide SIGNAL.
1785HANDLER is a Lisp function to be called when the signal is received.
944cc4a8
MA
1786It must accept as arguments the values SIGNAL is sending.
1787
1788All other arguments ARGS, if specified, must be strings. They stand
1789for the respective arguments of the signal in their order, and are
1790used for filtering as well. A nil argument might be used to preserve
1791the order.
1792
1793INTERFACE, SIGNAL and HANDLER must not be nil. Example:
033b73e2
MA
1794
1795\(defun my-signal-handler (device)
1796 (message "Device %s added" device))
1797
1798\(dbus-register-signal
52da95fa
MA
1799 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/Manager"
1800 "org.freedesktop.Hal.Manager" "DeviceAdded" 'my-signal-handler)
033b73e2 1801
f5306ca3
MA
1802 => ((:system "org.freedesktop.Hal.Manager" "DeviceAdded")
1803 ("org.freedesktop.Hal" "/org/freedesktop/Hal/Manager" my-signal-handler))
033b73e2
MA
1804
1805`dbus-register-signal' returns an object, which can be used in
944cc4a8
MA
1806`dbus-unregister-object' for removing the registration.
1807
1808usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARGS) */)
1809 (nargs, args)
1810 int nargs;
1811 register Lisp_Object *args;
033b73e2 1812{
944cc4a8
MA
1813 Lisp_Object bus, service, path, interface, signal, handler;
1814 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
17bc8f94 1815 Lisp_Object uname, key, key1, value;
033b73e2 1816 DBusConnection *connection;
944cc4a8 1817 int i;
52da95fa 1818 char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
c0894fb9 1819 char x[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
39abdd4a 1820 DBusError derror;
033b73e2
MA
1821
1822 /* Check parameters. */
944cc4a8
MA
1823 bus = args[0];
1824 service = args[1];
1825 path = args[2];
1826 interface = args[3];
1827 signal = args[4];
1828 handler = args[5];
1829
033b73e2 1830 CHECK_SYMBOL (bus);
39abdd4a
MA
1831 if (!NILP (service)) CHECK_STRING (service);
1832 if (!NILP (path)) CHECK_STRING (path);
033b73e2 1833 CHECK_STRING (interface);
52da95fa 1834 CHECK_STRING (signal);
17bc8f94
MA
1835 if (!FUNCTIONP (handler))
1836 wrong_type_argument (intern ("functionp"), handler);
944cc4a8 1837 GCPRO6 (bus, service, path, interface, signal, handler);
033b73e2 1838
52da95fa
MA
1839 /* Retrieve unique name of service. If service is a known name, we
1840 will register for the corresponding unique name, if any. Signals
1841 are sent always with the unique name as sender. Note: the unique
1842 name of "org.freedesktop.DBus" is that string itself. */
5125905e
MA
1843 if ((STRINGP (service))
1844 && (SBYTES (service) > 0)
eb7c7bf5
MA
1845 && (strcmp (SDATA (service), DBUS_SERVICE_DBUS) != 0)
1846 && (strncmp (SDATA (service), ":", 1) != 0))
f5306ca3
MA
1847 {
1848 uname = call2 (intern ("dbus-get-name-owner"), bus, service);
1849 /* When there is no unique name, we mark it with an empty
1850 string. */
1851 if (NILP (uname))
fff4e459 1852 uname = empty_unibyte_string;
f5306ca3 1853 }
52da95fa 1854 else
f5306ca3 1855 uname = service;
52da95fa 1856
f5306ca3
MA
1857 /* Create a matching rule if the unique name exists (when no
1858 wildcard). */
5125905e 1859 if (NILP (uname) || (SBYTES (uname) > 0))
f5306ca3
MA
1860 {
1861 /* Open a connection to the bus. */
1862 connection = xd_initialize (bus);
033b73e2 1863
f5306ca3
MA
1864 /* Create a rule to receive related signals. */
1865 sprintf (rule,
1866 "type='signal',interface='%s',member='%s'",
1867 SDATA (interface),
1868 SDATA (signal));
033b73e2 1869
f5306ca3
MA
1870 /* Add unique name and path to the rule if they are non-nil. */
1871 if (!NILP (uname))
c0894fb9
MA
1872 {
1873 sprintf (x, ",sender='%s'", SDATA (uname));
1874 strcat (rule, x);
1875 }
39abdd4a 1876
f5306ca3 1877 if (!NILP (path))
c0894fb9
MA
1878 {
1879 sprintf (x, ",path='%s'", SDATA (path));
1880 strcat (rule, x);
1881 }
39abdd4a 1882
944cc4a8
MA
1883 /* Add arguments to the rule if they are non-nil. */
1884 for (i = 6; i < nargs; ++i)
1885 if (!NILP (args[i]))
1886 {
1887 CHECK_STRING (args[i]);
c0894fb9
MA
1888 sprintf (x, ",arg%d='%s'", i-6, SDATA (args[i]));
1889 strcat (rule, x);
944cc4a8
MA
1890 }
1891
f5306ca3
MA
1892 /* Add the rule to the bus. */
1893 dbus_error_init (&derror);
1894 dbus_bus_add_match (connection, rule, &derror);
1895 if (dbus_error_is_set (&derror))
944cc4a8
MA
1896 {
1897 UNGCPRO;
1898 XD_ERROR (derror);
1899 }
033b73e2 1900
c1d5ce94
MA
1901 /* Cleanup. */
1902 dbus_error_free (&derror);
1903
f5306ca3
MA
1904 XD_DEBUG_MESSAGE ("Matching rule \"%s\" created", rule);
1905 }
033b73e2 1906
39abdd4a 1907 /* Create a hash table entry. */
a31d47c7 1908 key = list3 (bus, interface, signal);
17bc8f94 1909 key1 = list4 (uname, service, path, handler);
f04bb9b2 1910 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
17bc8f94
MA
1911
1912 if (NILP (Fmember (key1, value)))
f04bb9b2 1913 Fputhash (key, Fcons (key1, value), Vdbus_registered_objects_table);
17bc8f94
MA
1914
1915 /* Return object. */
944cc4a8 1916 RETURN_UNGCPRO (list2 (key, list3 (service, path, handler)));
17bc8f94
MA
1917}
1918
1919DEFUN ("dbus-register-method", Fdbus_register_method, Sdbus_register_method,
1920 6, 6, 0,
1921 doc: /* Register for method METHOD on the D-Bus BUS.
1922
1923BUS is either the symbol `:system' or the symbol `:session'.
1924
1925SERVICE is the D-Bus service name of the D-Bus object METHOD is
1926registered for. It must be a known name.
1927
1928PATH is the D-Bus object path SERVICE is registered. INTERFACE is the
1929interface offered by SERVICE. It must provide METHOD. HANDLER is a
1930Lisp function to be called when a method call is received. It must
1931accept the input arguments of METHOD. The return value of HANDLER is
abe136ee 1932used for composing the returning D-Bus message. */)
17bc8f94
MA
1933 (bus, service, path, interface, method, handler)
1934 Lisp_Object bus, service, path, interface, method, handler;
1935{
1936 Lisp_Object key, key1, value;
1937 DBusConnection *connection;
1938 int result;
1939 DBusError derror;
1940
17bc8f94
MA
1941 /* Check parameters. */
1942 CHECK_SYMBOL (bus);
1943 CHECK_STRING (service);
1944 CHECK_STRING (path);
1945 CHECK_STRING (interface);
1946 CHECK_STRING (method);
1947 if (!FUNCTIONP (handler))
1948 wrong_type_argument (intern ("functionp"), handler);
1949 /* TODO: We must check for a valid service name, otherwise there is
1950 a segmentation fault. */
1951
1952 /* Open a connection to the bus. */
1953 connection = xd_initialize (bus);
1954
1955 /* Request the known name from the bus. We can ignore the result,
1956 it is set to -1 if there is an error - kind of redundancy. */
1957 dbus_error_init (&derror);
1958 result = dbus_bus_request_name (connection, SDATA (service), 0, &derror);
1959 if (dbus_error_is_set (&derror))
1960 XD_ERROR (derror);
1961
f04bb9b2
MA
1962 /* Create a hash table entry. We use nil for the unique name,
1963 because the method might be called from anybody. */
17bc8f94
MA
1964 key = list3 (bus, interface, method);
1965 key1 = list4 (Qnil, service, path, handler);
f04bb9b2 1966 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
a31d47c7 1967
17bc8f94 1968 if (NILP (Fmember (key1, value)))
f04bb9b2 1969 Fputhash (key, Fcons (key1, value), Vdbus_registered_objects_table);
033b73e2 1970
c1d5ce94
MA
1971 /* Cleanup. */
1972 dbus_error_free (&derror);
1973
f5306ca3
MA
1974 /* Return object. */
1975 return list2 (key, list3 (service, path, handler));
033b73e2
MA
1976}
1977
033b73e2
MA
1978\f
1979void
1980syms_of_dbusbind ()
1981{
1982
d67b4f80 1983 Qdbus_init_bus = intern_c_string ("dbus-init-bus");
058ed861
MA
1984 staticpro (&Qdbus_init_bus);
1985 defsubr (&Sdbus_init_bus);
1986
d67b4f80 1987 Qdbus_get_unique_name = intern_c_string ("dbus-get-unique-name");
033b73e2
MA
1988 staticpro (&Qdbus_get_unique_name);
1989 defsubr (&Sdbus_get_unique_name);
1990
d67b4f80 1991 Qdbus_call_method = intern_c_string ("dbus-call-method");
033b73e2
MA
1992 staticpro (&Qdbus_call_method);
1993 defsubr (&Sdbus_call_method);
1994
d67b4f80 1995 Qdbus_call_method_asynchronously = intern_c_string ("dbus-call-method-asynchronously");
13ecc6dc
MA
1996 staticpro (&Qdbus_call_method_asynchronously);
1997 defsubr (&Sdbus_call_method_asynchronously);
1998
d67b4f80 1999 Qdbus_method_return_internal = intern_c_string ("dbus-method-return-internal");
8c7a4ac5
MA
2000 staticpro (&Qdbus_method_return_internal);
2001 defsubr (&Sdbus_method_return_internal);
abe136ee 2002
d67b4f80 2003 Qdbus_method_error_internal = intern_c_string ("dbus-method-error-internal");
13ecc6dc
MA
2004 staticpro (&Qdbus_method_error_internal);
2005 defsubr (&Sdbus_method_error_internal);
2006
d67b4f80 2007 Qdbus_send_signal = intern_c_string ("dbus-send-signal");
033b73e2
MA
2008 staticpro (&Qdbus_send_signal);
2009 defsubr (&Sdbus_send_signal);
2010
d67b4f80 2011 Qdbus_register_signal = intern_c_string ("dbus-register-signal");
033b73e2
MA
2012 staticpro (&Qdbus_register_signal);
2013 defsubr (&Sdbus_register_signal);
2014
d67b4f80 2015 Qdbus_register_method = intern_c_string ("dbus-register-method");
17bc8f94
MA
2016 staticpro (&Qdbus_register_method);
2017 defsubr (&Sdbus_register_method);
2018
d67b4f80 2019 Qdbus_error = intern_c_string ("dbus-error");
033b73e2
MA
2020 staticpro (&Qdbus_error);
2021 Fput (Qdbus_error, Qerror_conditions,
2022 list2 (Qdbus_error, Qerror));
2023 Fput (Qdbus_error, Qerror_message,
d67b4f80 2024 make_pure_c_string ("D-Bus error"));
033b73e2 2025
d67b4f80 2026 QCdbus_system_bus = intern_c_string (":system");
39abdd4a
MA
2027 staticpro (&QCdbus_system_bus);
2028
d67b4f80 2029 QCdbus_session_bus = intern_c_string (":session");
39abdd4a 2030 staticpro (&QCdbus_session_bus);
033b73e2 2031
d67b4f80 2032 QCdbus_timeout = intern_c_string (":timeout");
90b3fc84
MA
2033 staticpro (&QCdbus_timeout);
2034
d67b4f80 2035 QCdbus_type_byte = intern_c_string (":byte");
54371585
MA
2036 staticpro (&QCdbus_type_byte);
2037
d67b4f80 2038 QCdbus_type_boolean = intern_c_string (":boolean");
54371585
MA
2039 staticpro (&QCdbus_type_boolean);
2040
d67b4f80 2041 QCdbus_type_int16 = intern_c_string (":int16");
54371585
MA
2042 staticpro (&QCdbus_type_int16);
2043
d67b4f80 2044 QCdbus_type_uint16 = intern_c_string (":uint16");
54371585
MA
2045 staticpro (&QCdbus_type_uint16);
2046
d67b4f80 2047 QCdbus_type_int32 = intern_c_string (":int32");
54371585
MA
2048 staticpro (&QCdbus_type_int32);
2049
d67b4f80 2050 QCdbus_type_uint32 = intern_c_string (":uint32");
54371585
MA
2051 staticpro (&QCdbus_type_uint32);
2052
d67b4f80 2053 QCdbus_type_int64 = intern_c_string (":int64");
54371585
MA
2054 staticpro (&QCdbus_type_int64);
2055
d67b4f80 2056 QCdbus_type_uint64 = intern_c_string (":uint64");
54371585
MA
2057 staticpro (&QCdbus_type_uint64);
2058
d67b4f80 2059 QCdbus_type_double = intern_c_string (":double");
54371585
MA
2060 staticpro (&QCdbus_type_double);
2061
d67b4f80 2062 QCdbus_type_string = intern_c_string (":string");
54371585
MA
2063 staticpro (&QCdbus_type_string);
2064
d67b4f80 2065 QCdbus_type_object_path = intern_c_string (":object-path");
54371585
MA
2066 staticpro (&QCdbus_type_object_path);
2067
d67b4f80 2068 QCdbus_type_signature = intern_c_string (":signature");
54371585
MA
2069 staticpro (&QCdbus_type_signature);
2070
d67b4f80 2071 QCdbus_type_array = intern_c_string (":array");
54371585
MA
2072 staticpro (&QCdbus_type_array);
2073
d67b4f80 2074 QCdbus_type_variant = intern_c_string (":variant");
54371585
MA
2075 staticpro (&QCdbus_type_variant);
2076
d67b4f80 2077 QCdbus_type_struct = intern_c_string (":struct");
54371585
MA
2078 staticpro (&QCdbus_type_struct);
2079
d67b4f80 2080 QCdbus_type_dict_entry = intern_c_string (":dict-entry");
54371585
MA
2081 staticpro (&QCdbus_type_dict_entry);
2082
f04bb9b2
MA
2083 DEFVAR_LISP ("dbus-registered-objects-table",
2084 &Vdbus_registered_objects_table,
39abdd4a 2085 doc: /* Hash table of registered functions for D-Bus.
f04bb9b2
MA
2086There are two different uses of the hash table: for accessing
2087registered interfaces properties, targeted by signals or method calls,
2088and for calling handlers in case of non-blocking method call returns.
13ecc6dc
MA
2089
2090In the first case, the key in the hash table is the list (BUS
2091INTERFACE MEMBER). BUS is either the symbol `:system' or the symbol
2092`:session'. INTERFACE is a string which denotes a D-Bus interface,
f04bb9b2
MA
2093and MEMBER, also a string, is either a method, a signal or a property
2094INTERFACE is offering. All arguments but BUS must not be nil.
a31d47c7 2095
f5306ca3 2096The value in the hash table is a list of quadruple lists
f04bb9b2 2097\((UNAME SERVICE PATH OBJECT) (UNAME SERVICE PATH OBJECT) ...).
a31d47c7 2098SERVICE is the service name as registered, UNAME is the corresponding
f04bb9b2
MA
2099unique name. In case of registered methods and properties, UNAME is
2100nil. PATH is the object path of the sending object. All of them can
2101be nil, which means a wildcard then. OBJECT is either the handler to
2102be called when a D-Bus message, which matches the key criteria,
2103arrives (methods and signals), or a cons cell containing the value of
2104the property.
13ecc6dc
MA
2105
2106In the second case, the key in the hash table is the list (BUS SERIAL).
2107BUS is either the symbol `:system' or the symbol `:session'. SERIAL
2108is the serial number of the non-blocking method call, a reply is
2109expected. Both arguments must not be nil. The value in the hash
2110table is HANDLER, the function to be called when the D-Bus reply
2111message arrives. */);
f04bb9b2
MA
2112 /* We initialize Vdbus_registered_objects_table in dbus.el, because
2113 we need to define a hash table function first. */
2114 Vdbus_registered_objects_table = Qnil;
033b73e2
MA
2115
2116 DEFVAR_LISP ("dbus-debug", &Vdbus_debug,
39abdd4a 2117 doc: /* If non-nil, debug messages of D-Bus bindings are raised. */);
033b73e2
MA
2118#ifdef DBUS_DEBUG
2119 Vdbus_debug = Qt;
2120#else
2121 Vdbus_debug = Qnil;
2122#endif
2123
d67b4f80 2124 Fprovide (intern_c_string ("dbusbind"), Qnil);
033b73e2
MA
2125
2126}
2127
2128#endif /* HAVE_DBUS */
79f10da0
MB
2129
2130/* arch-tag: 0e828477-b571-4fe4-b559-5c9211bc14b8
2131 (do not change this comment) */