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