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