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