Declare Lisp_Object Q* variables to be 'static' if not exproted.
[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 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 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 %u", dtype, (unsigned int) val);
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 (data != NULL && data == (void*) XHASH (QCdbus_session_bus))
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
923 /* Open a connection to the bus. */
924 connection = xd_initialize (bus, TRUE);
925
926 /* Add the watch functions. We pass also the bus as data, in order
927 to distinguish between the busses in xd_remove_watch. */
928 if (!dbus_connection_set_watch_functions (connection,
929 xd_add_watch,
930 xd_remove_watch,
931 xd_toggle_watch,
932 (void*) XHASH (bus), NULL))
933 XD_SIGNAL1 (build_string ("Cannot add watch functions"));
934
935 /* Add bus to list of registered buses. */
936 Vdbus_registered_buses = Fcons (bus, Vdbus_registered_buses);
937
938 /* We do not want to abort. */
939 putenv ((char *) "DBUS_FATAL_WARNINGS=0");
940
941 /* Return. */
942 return Qnil;
943 }
944
945 DEFUN ("dbus-close-bus", Fdbus_close_bus, Sdbus_close_bus, 1, 1, 0,
946 doc: /* Close connection to D-Bus BUS. */)
947 (Lisp_Object bus)
948 {
949 DBusConnection *connection;
950
951 /* Open a connection to the bus. */
952 connection = xd_initialize (bus, TRUE);
953
954 /* Decrement reference count to the bus. */
955 dbus_connection_unref (connection);
956
957 /* Remove bus from list of registered buses. */
958 Vdbus_registered_buses = Fdelete (bus, Vdbus_registered_buses);
959
960 /* Return. */
961 return Qnil;
962 }
963
964 DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name,
965 1, 1, 0,
966 doc: /* Return the unique name of Emacs registered at D-Bus BUS. */)
967 (Lisp_Object bus)
968 {
969 DBusConnection *connection;
970 const char *name;
971
972 /* Open a connection to the bus. */
973 connection = xd_initialize (bus, TRUE);
974
975 /* Request the name. */
976 name = dbus_bus_get_unique_name (connection);
977 if (name == NULL)
978 XD_SIGNAL1 (build_string ("No unique name available"));
979
980 /* Return. */
981 return build_string (name);
982 }
983
984 DEFUN ("dbus-call-method", Fdbus_call_method, Sdbus_call_method, 5, MANY, 0,
985 doc: /* Call METHOD on the D-Bus BUS.
986
987 BUS is either a Lisp symbol, `:system' or `:session', or a string
988 denoting the bus address.
989
990 SERVICE is the D-Bus service name to be used. PATH is the D-Bus
991 object path SERVICE is registered at. INTERFACE is an interface
992 offered by SERVICE. It must provide METHOD.
993
994 If the parameter `:timeout' is given, the following integer TIMEOUT
995 specifies the maximum number of milliseconds the method call must
996 return. The default value is 25,000. If the method call doesn't
997 return in time, a D-Bus error is raised.
998
999 All other arguments ARGS are passed to METHOD as arguments. They are
1000 converted into D-Bus types via the following rules:
1001
1002 t and nil => DBUS_TYPE_BOOLEAN
1003 number => DBUS_TYPE_UINT32
1004 integer => DBUS_TYPE_INT32
1005 float => DBUS_TYPE_DOUBLE
1006 string => DBUS_TYPE_STRING
1007 list => DBUS_TYPE_ARRAY
1008
1009 All arguments can be preceded by a type symbol. For details about
1010 type symbols, see Info node `(dbus)Type Conversion'.
1011
1012 `dbus-call-method' returns the resulting values of METHOD as a list of
1013 Lisp objects. The type conversion happens the other direction as for
1014 input arguments. It follows the mapping rules:
1015
1016 DBUS_TYPE_BOOLEAN => t or nil
1017 DBUS_TYPE_BYTE => number
1018 DBUS_TYPE_UINT16 => number
1019 DBUS_TYPE_INT16 => integer
1020 DBUS_TYPE_UINT32 => number or float
1021 DBUS_TYPE_UNIX_FD => number or float
1022 DBUS_TYPE_INT32 => integer or float
1023 DBUS_TYPE_UINT64 => number or float
1024 DBUS_TYPE_INT64 => integer or float
1025 DBUS_TYPE_DOUBLE => float
1026 DBUS_TYPE_STRING => string
1027 DBUS_TYPE_OBJECT_PATH => string
1028 DBUS_TYPE_SIGNATURE => string
1029 DBUS_TYPE_ARRAY => list
1030 DBUS_TYPE_VARIANT => list
1031 DBUS_TYPE_STRUCT => list
1032 DBUS_TYPE_DICT_ENTRY => list
1033
1034 Example:
1035
1036 \(dbus-call-method
1037 :session "org.gnome.seahorse" "/org/gnome/seahorse/keys/openpgp"
1038 "org.gnome.seahorse.Keys" "GetKeyField"
1039 "openpgp:657984B8C7A966DD" "simple-name")
1040
1041 => (t ("Philip R. Zimmermann"))
1042
1043 If the result of the METHOD call is just one value, the converted Lisp
1044 object is returned instead of a list containing this single Lisp object.
1045
1046 \(dbus-call-method
1047 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer"
1048 "org.freedesktop.Hal.Device" "GetPropertyString"
1049 "system.kernel.machine")
1050
1051 => "i686"
1052
1053 usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &optional :timeout TIMEOUT &rest ARGS) */)
1054 (size_t nargs, register Lisp_Object *args)
1055 {
1056 Lisp_Object bus, service, path, interface, method;
1057 Lisp_Object result;
1058 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
1059 DBusConnection *connection;
1060 DBusMessage *dmessage;
1061 DBusMessage *reply;
1062 DBusMessageIter iter;
1063 DBusError derror;
1064 unsigned int dtype;
1065 int timeout = -1;
1066 size_t i = 5;
1067 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1068
1069 /* Check parameters. */
1070 bus = args[0];
1071 service = args[1];
1072 path = args[2];
1073 interface = args[3];
1074 method = args[4];
1075
1076 CHECK_STRING (service);
1077 CHECK_STRING (path);
1078 CHECK_STRING (interface);
1079 CHECK_STRING (method);
1080 GCPRO5 (bus, service, path, interface, method);
1081
1082 XD_DEBUG_MESSAGE ("%s %s %s %s",
1083 SDATA (service),
1084 SDATA (path),
1085 SDATA (interface),
1086 SDATA (method));
1087
1088 /* Open a connection to the bus. */
1089 connection = xd_initialize (bus, TRUE);
1090
1091 /* Create the message. */
1092 dmessage = dbus_message_new_method_call (SSDATA (service),
1093 SSDATA (path),
1094 SSDATA (interface),
1095 SSDATA (method));
1096 UNGCPRO;
1097 if (dmessage == NULL)
1098 XD_SIGNAL1 (build_string ("Unable to create a new message"));
1099
1100 /* Check for timeout parameter. */
1101 if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
1102 {
1103 CHECK_NATNUM (args[i+1]);
1104 timeout = XUINT (args[i+1]);
1105 i = i+2;
1106 }
1107
1108 /* Initialize parameter list of message. */
1109 dbus_message_iter_init_append (dmessage, &iter);
1110
1111 /* Append parameters to the message. */
1112 for (; i < nargs; ++i)
1113 {
1114 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1115 if (XD_DBUS_TYPE_P (args[i]))
1116 {
1117 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1118 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1119 XD_DEBUG_MESSAGE ("Parameter%lu %s %s", (unsigned long) (i-4),
1120 SDATA (format2 ("%s", args[i], Qnil)),
1121 SDATA (format2 ("%s", args[i+1], Qnil)));
1122 ++i;
1123 }
1124 else
1125 {
1126 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1127 XD_DEBUG_MESSAGE ("Parameter%lu %s", (unsigned long) (i-4),
1128 SDATA (format2 ("%s", args[i], Qnil)));
1129 }
1130
1131 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1132 indication that there is no parent type. */
1133 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1134
1135 xd_append_arg (dtype, args[i], &iter);
1136 }
1137
1138 /* Send the message. */
1139 dbus_error_init (&derror);
1140 reply = dbus_connection_send_with_reply_and_block (connection,
1141 dmessage,
1142 timeout,
1143 &derror);
1144
1145 if (dbus_error_is_set (&derror))
1146 XD_ERROR (derror);
1147
1148 if (reply == NULL)
1149 XD_SIGNAL1 (build_string ("No reply"));
1150
1151 XD_DEBUG_MESSAGE ("Message sent");
1152
1153 /* Collect the results. */
1154 result = Qnil;
1155 GCPRO1 (result);
1156
1157 if (dbus_message_iter_init (reply, &iter))
1158 {
1159 /* Loop over the parameters of the D-Bus reply message. Construct a
1160 Lisp list, which is returned by `dbus-call-method'. */
1161 while ((dtype = dbus_message_iter_get_arg_type (&iter))
1162 != DBUS_TYPE_INVALID)
1163 {
1164 result = Fcons (xd_retrieve_arg (dtype, &iter), result);
1165 dbus_message_iter_next (&iter);
1166 }
1167 }
1168 else
1169 {
1170 /* No arguments: just return nil. */
1171 }
1172
1173 /* Cleanup. */
1174 dbus_error_free (&derror);
1175 dbus_message_unref (dmessage);
1176 dbus_message_unref (reply);
1177
1178 /* Return the result. If there is only one single Lisp object,
1179 return it as-it-is, otherwise return the reversed list. */
1180 if (XUINT (Flength (result)) == 1)
1181 RETURN_UNGCPRO (CAR_SAFE (result));
1182 else
1183 RETURN_UNGCPRO (Fnreverse (result));
1184 }
1185
1186 DEFUN ("dbus-call-method-asynchronously", Fdbus_call_method_asynchronously,
1187 Sdbus_call_method_asynchronously, 6, MANY, 0,
1188 doc: /* Call METHOD on the D-Bus BUS asynchronously.
1189
1190 BUS is either a Lisp symbol, `:system' or `:session', or a string
1191 denoting the bus address.
1192
1193 SERVICE is the D-Bus service name to be used. PATH is the D-Bus
1194 object path SERVICE is registered at. INTERFACE is an interface
1195 offered by SERVICE. It must provide METHOD.
1196
1197 HANDLER is a Lisp function, which is called when the corresponding
1198 return message has arrived. If HANDLER is nil, no return message will
1199 be expected.
1200
1201 If the parameter `:timeout' is given, the following integer TIMEOUT
1202 specifies the maximum number of milliseconds the method call must
1203 return. The default value is 25,000. If the method call doesn't
1204 return in time, a D-Bus error is raised.
1205
1206 All other arguments ARGS are passed to METHOD as arguments. They are
1207 converted into D-Bus types via the following rules:
1208
1209 t and nil => DBUS_TYPE_BOOLEAN
1210 number => DBUS_TYPE_UINT32
1211 integer => DBUS_TYPE_INT32
1212 float => DBUS_TYPE_DOUBLE
1213 string => DBUS_TYPE_STRING
1214 list => DBUS_TYPE_ARRAY
1215
1216 All arguments can be preceded by a type symbol. For details about
1217 type symbols, see Info node `(dbus)Type Conversion'.
1218
1219 Unless HANDLER is nil, the function returns a key into the hash table
1220 `dbus-registered-objects-table'. The corresponding entry in the hash
1221 table is removed, when the return message has been arrived, and
1222 HANDLER is called.
1223
1224 Example:
1225
1226 \(dbus-call-method-asynchronously
1227 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer"
1228 "org.freedesktop.Hal.Device" "GetPropertyString" 'message
1229 "system.kernel.machine")
1230
1231 => (:system 2)
1232
1233 -| i686
1234
1235 usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLER &optional :timeout TIMEOUT &rest ARGS) */)
1236 (size_t nargs, register Lisp_Object *args)
1237 {
1238 Lisp_Object bus, service, path, interface, method, handler;
1239 Lisp_Object result;
1240 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
1241 DBusConnection *connection;
1242 DBusMessage *dmessage;
1243 DBusMessageIter iter;
1244 unsigned int dtype;
1245 int timeout = -1;
1246 size_t i = 6;
1247 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1248
1249 /* Check parameters. */
1250 bus = args[0];
1251 service = args[1];
1252 path = args[2];
1253 interface = args[3];
1254 method = args[4];
1255 handler = args[5];
1256
1257 CHECK_STRING (service);
1258 CHECK_STRING (path);
1259 CHECK_STRING (interface);
1260 CHECK_STRING (method);
1261 if (!NILP (handler) && !FUNCTIONP (handler))
1262 wrong_type_argument (intern ("functionp"), handler);
1263 GCPRO6 (bus, service, path, interface, method, handler);
1264
1265 XD_DEBUG_MESSAGE ("%s %s %s %s",
1266 SDATA (service),
1267 SDATA (path),
1268 SDATA (interface),
1269 SDATA (method));
1270
1271 /* Open a connection to the bus. */
1272 connection = xd_initialize (bus, TRUE);
1273
1274 /* Create the message. */
1275 dmessage = dbus_message_new_method_call (SSDATA (service),
1276 SSDATA (path),
1277 SSDATA (interface),
1278 SSDATA (method));
1279 if (dmessage == NULL)
1280 XD_SIGNAL1 (build_string ("Unable to create a new message"));
1281
1282 /* Check for timeout parameter. */
1283 if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
1284 {
1285 CHECK_NATNUM (args[i+1]);
1286 timeout = XUINT (args[i+1]);
1287 i = i+2;
1288 }
1289
1290 /* Initialize parameter list of message. */
1291 dbus_message_iter_init_append (dmessage, &iter);
1292
1293 /* Append parameters to the message. */
1294 for (; i < nargs; ++i)
1295 {
1296 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1297 if (XD_DBUS_TYPE_P (args[i]))
1298 {
1299 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1300 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1301 XD_DEBUG_MESSAGE ("Parameter%lu %s %s", (unsigned long) (i-4),
1302 SDATA (format2 ("%s", args[i], Qnil)),
1303 SDATA (format2 ("%s", args[i+1], Qnil)));
1304 ++i;
1305 }
1306 else
1307 {
1308 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1309 XD_DEBUG_MESSAGE ("Parameter%lu %s", (unsigned long) (i - 4),
1310 SDATA (format2 ("%s", args[i], Qnil)));
1311 }
1312
1313 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1314 indication that there is no parent type. */
1315 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1316
1317 xd_append_arg (dtype, args[i], &iter);
1318 }
1319
1320 if (!NILP (handler))
1321 {
1322 /* Send the message. The message is just added to the outgoing
1323 message queue. */
1324 if (!dbus_connection_send_with_reply (connection, dmessage,
1325 NULL, timeout))
1326 XD_SIGNAL1 (build_string ("Cannot send message"));
1327
1328 /* The result is the key in Vdbus_registered_objects_table. */
1329 result = (list2 (bus, make_number (dbus_message_get_serial (dmessage))));
1330
1331 /* Create a hash table entry. */
1332 Fputhash (result, handler, Vdbus_registered_objects_table);
1333 }
1334 else
1335 {
1336 /* Send the message. The message is just added to the outgoing
1337 message queue. */
1338 if (!dbus_connection_send (connection, dmessage, NULL))
1339 XD_SIGNAL1 (build_string ("Cannot send message"));
1340
1341 result = Qnil;
1342 }
1343
1344 XD_DEBUG_MESSAGE ("Message sent");
1345
1346 /* Cleanup. */
1347 dbus_message_unref (dmessage);
1348
1349 /* Return the result. */
1350 RETURN_UNGCPRO (result);
1351 }
1352
1353 DEFUN ("dbus-method-return-internal", Fdbus_method_return_internal,
1354 Sdbus_method_return_internal,
1355 3, MANY, 0,
1356 doc: /* Return for message SERIAL on the D-Bus BUS.
1357 This is an internal function, it shall not be used outside dbus.el.
1358
1359 usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */)
1360 (size_t nargs, register Lisp_Object *args)
1361 {
1362 Lisp_Object bus, serial, service;
1363 struct gcpro gcpro1, gcpro2, gcpro3;
1364 DBusConnection *connection;
1365 DBusMessage *dmessage;
1366 DBusMessageIter iter;
1367 unsigned int dtype;
1368 size_t i;
1369 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1370
1371 /* Check parameters. */
1372 bus = args[0];
1373 serial = args[1];
1374 service = args[2];
1375
1376 CHECK_NUMBER (serial);
1377 CHECK_STRING (service);
1378 GCPRO3 (bus, serial, service);
1379
1380 XD_DEBUG_MESSAGE ("%lu %s ", (unsigned long) XUINT (serial), SDATA (service));
1381
1382 /* Open a connection to the bus. */
1383 connection = xd_initialize (bus, TRUE);
1384
1385 /* Create the message. */
1386 dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
1387 if ((dmessage == NULL)
1388 || (!dbus_message_set_reply_serial (dmessage, XUINT (serial)))
1389 || (!dbus_message_set_destination (dmessage, SSDATA (service))))
1390 {
1391 UNGCPRO;
1392 XD_SIGNAL1 (build_string ("Unable to create a return message"));
1393 }
1394
1395 UNGCPRO;
1396
1397 /* Initialize parameter list of message. */
1398 dbus_message_iter_init_append (dmessage, &iter);
1399
1400 /* Append parameters to the message. */
1401 for (i = 3; i < nargs; ++i)
1402 {
1403 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1404 if (XD_DBUS_TYPE_P (args[i]))
1405 {
1406 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1407 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1408 XD_DEBUG_MESSAGE ("Parameter%lu %s %s", (unsigned long) (i-2),
1409 SDATA (format2 ("%s", args[i], Qnil)),
1410 SDATA (format2 ("%s", args[i+1], Qnil)));
1411 ++i;
1412 }
1413 else
1414 {
1415 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1416 XD_DEBUG_MESSAGE ("Parameter%lu %s", (unsigned long) (i-2),
1417 SDATA (format2 ("%s", args[i], Qnil)));
1418 }
1419
1420 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1421 indication that there is no parent type. */
1422 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1423
1424 xd_append_arg (dtype, args[i], &iter);
1425 }
1426
1427 /* Send the message. The message is just added to the outgoing
1428 message queue. */
1429 if (!dbus_connection_send (connection, dmessage, NULL))
1430 XD_SIGNAL1 (build_string ("Cannot send message"));
1431
1432 XD_DEBUG_MESSAGE ("Message sent");
1433
1434 /* Cleanup. */
1435 dbus_message_unref (dmessage);
1436
1437 /* Return. */
1438 return Qt;
1439 }
1440
1441 DEFUN ("dbus-method-error-internal", Fdbus_method_error_internal,
1442 Sdbus_method_error_internal,
1443 3, MANY, 0,
1444 doc: /* Return error message for message SERIAL on the D-Bus BUS.
1445 This is an internal function, it shall not be used outside dbus.el.
1446
1447 usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */)
1448 (size_t nargs, register Lisp_Object *args)
1449 {
1450 Lisp_Object bus, serial, service;
1451 struct gcpro gcpro1, gcpro2, gcpro3;
1452 DBusConnection *connection;
1453 DBusMessage *dmessage;
1454 DBusMessageIter iter;
1455 unsigned int dtype;
1456 size_t i;
1457 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1458
1459 /* Check parameters. */
1460 bus = args[0];
1461 serial = args[1];
1462 service = args[2];
1463
1464 CHECK_NUMBER (serial);
1465 CHECK_STRING (service);
1466 GCPRO3 (bus, serial, service);
1467
1468 XD_DEBUG_MESSAGE ("%lu %s ", (unsigned long) XUINT (serial), SDATA (service));
1469
1470 /* Open a connection to the bus. */
1471 connection = xd_initialize (bus, TRUE);
1472
1473 /* Create the message. */
1474 dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
1475 if ((dmessage == NULL)
1476 || (!dbus_message_set_error_name (dmessage, DBUS_ERROR_FAILED))
1477 || (!dbus_message_set_reply_serial (dmessage, XUINT (serial)))
1478 || (!dbus_message_set_destination (dmessage, SSDATA (service))))
1479 {
1480 UNGCPRO;
1481 XD_SIGNAL1 (build_string ("Unable to create a error message"));
1482 }
1483
1484 UNGCPRO;
1485
1486 /* Initialize parameter list of message. */
1487 dbus_message_iter_init_append (dmessage, &iter);
1488
1489 /* Append parameters to the message. */
1490 for (i = 3; i < nargs; ++i)
1491 {
1492 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1493 if (XD_DBUS_TYPE_P (args[i]))
1494 {
1495 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1496 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1497 XD_DEBUG_MESSAGE ("Parameter%lu %s %s", (unsigned long) (i-2),
1498 SDATA (format2 ("%s", args[i], Qnil)),
1499 SDATA (format2 ("%s", args[i+1], Qnil)));
1500 ++i;
1501 }
1502 else
1503 {
1504 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1505 XD_DEBUG_MESSAGE ("Parameter%lu %s", (unsigned long) (i-2),
1506 SDATA (format2 ("%s", args[i], Qnil)));
1507 }
1508
1509 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1510 indication that there is no parent type. */
1511 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1512
1513 xd_append_arg (dtype, args[i], &iter);
1514 }
1515
1516 /* Send the message. The message is just added to the outgoing
1517 message queue. */
1518 if (!dbus_connection_send (connection, dmessage, NULL))
1519 XD_SIGNAL1 (build_string ("Cannot send message"));
1520
1521 XD_DEBUG_MESSAGE ("Message sent");
1522
1523 /* Cleanup. */
1524 dbus_message_unref (dmessage);
1525
1526 /* Return. */
1527 return Qt;
1528 }
1529
1530 DEFUN ("dbus-send-signal", Fdbus_send_signal, Sdbus_send_signal, 5, MANY, 0,
1531 doc: /* Send signal SIGNAL on the D-Bus BUS.
1532
1533 BUS is either a Lisp symbol, `:system' or `:session', or a string
1534 denoting the bus address.
1535
1536 SERVICE is the D-Bus service name SIGNAL is sent from. PATH is the
1537 D-Bus object path SERVICE is registered at. INTERFACE is an interface
1538 offered by SERVICE. It must provide signal SIGNAL.
1539
1540 All other arguments ARGS are passed to SIGNAL as arguments. They are
1541 converted into D-Bus types via the following rules:
1542
1543 t and nil => DBUS_TYPE_BOOLEAN
1544 number => DBUS_TYPE_UINT32
1545 integer => DBUS_TYPE_INT32
1546 float => DBUS_TYPE_DOUBLE
1547 string => DBUS_TYPE_STRING
1548 list => DBUS_TYPE_ARRAY
1549
1550 All arguments can be preceded by a type symbol. For details about
1551 type symbols, see Info node `(dbus)Type Conversion'.
1552
1553 Example:
1554
1555 \(dbus-send-signal
1556 :session "org.gnu.Emacs" "/org/gnu/Emacs"
1557 "org.gnu.Emacs.FileManager" "FileModified" "/home/albinus/.emacs")
1558
1559 usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
1560 (size_t nargs, register Lisp_Object *args)
1561 {
1562 Lisp_Object bus, service, path, interface, signal;
1563 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
1564 DBusConnection *connection;
1565 DBusMessage *dmessage;
1566 DBusMessageIter iter;
1567 unsigned int dtype;
1568 size_t i;
1569 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1570
1571 /* Check parameters. */
1572 bus = args[0];
1573 service = args[1];
1574 path = args[2];
1575 interface = args[3];
1576 signal = args[4];
1577
1578 CHECK_STRING (service);
1579 CHECK_STRING (path);
1580 CHECK_STRING (interface);
1581 CHECK_STRING (signal);
1582 GCPRO5 (bus, service, path, interface, signal);
1583
1584 XD_DEBUG_MESSAGE ("%s %s %s %s",
1585 SDATA (service),
1586 SDATA (path),
1587 SDATA (interface),
1588 SDATA (signal));
1589
1590 /* Open a connection to the bus. */
1591 connection = xd_initialize (bus, TRUE);
1592
1593 /* Create the message. */
1594 dmessage = dbus_message_new_signal (SSDATA (path),
1595 SSDATA (interface),
1596 SSDATA (signal));
1597 UNGCPRO;
1598 if (dmessage == NULL)
1599 XD_SIGNAL1 (build_string ("Unable to create a new message"));
1600
1601 /* Initialize parameter list of message. */
1602 dbus_message_iter_init_append (dmessage, &iter);
1603
1604 /* Append parameters to the message. */
1605 for (i = 5; i < nargs; ++i)
1606 {
1607 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1608 if (XD_DBUS_TYPE_P (args[i]))
1609 {
1610 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1611 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1612 XD_DEBUG_MESSAGE ("Parameter%lu %s %s", (unsigned long) (i-4),
1613 SDATA (format2 ("%s", args[i], Qnil)),
1614 SDATA (format2 ("%s", args[i+1], Qnil)));
1615 ++i;
1616 }
1617 else
1618 {
1619 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1620 XD_DEBUG_MESSAGE ("Parameter%lu %s", (unsigned long) (i-4),
1621 SDATA (format2 ("%s", args[i], Qnil)));
1622 }
1623
1624 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1625 indication that there is no parent type. */
1626 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1627
1628 xd_append_arg (dtype, args[i], &iter);
1629 }
1630
1631 /* Send the message. The message is just added to the outgoing
1632 message queue. */
1633 if (!dbus_connection_send (connection, dmessage, NULL))
1634 XD_SIGNAL1 (build_string ("Cannot send message"));
1635
1636 XD_DEBUG_MESSAGE ("Signal sent");
1637
1638 /* Cleanup. */
1639 dbus_message_unref (dmessage);
1640
1641 /* Return. */
1642 return Qt;
1643 }
1644
1645 /* Read one queued incoming message of the D-Bus BUS.
1646 BUS is either a Lisp symbol, :system or :session, or a string denoting
1647 the bus address. */
1648 static void
1649 xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
1650 {
1651 Lisp_Object args, key, value;
1652 struct gcpro gcpro1;
1653 struct input_event event;
1654 DBusMessage *dmessage;
1655 DBusMessageIter iter;
1656 unsigned int dtype;
1657 int mtype, serial;
1658 const char *uname, *path, *interface, *member;
1659
1660 dmessage = dbus_connection_pop_message (connection);
1661
1662 /* Return if there is no queued message. */
1663 if (dmessage == NULL)
1664 return;
1665
1666 /* Collect the parameters. */
1667 args = Qnil;
1668 GCPRO1 (args);
1669
1670 /* Loop over the resulting parameters. Construct a list. */
1671 if (dbus_message_iter_init (dmessage, &iter))
1672 {
1673 while ((dtype = dbus_message_iter_get_arg_type (&iter))
1674 != DBUS_TYPE_INVALID)
1675 {
1676 args = Fcons (xd_retrieve_arg (dtype, &iter), args);
1677 dbus_message_iter_next (&iter);
1678 }
1679 /* The arguments are stored in reverse order. Reorder them. */
1680 args = Fnreverse (args);
1681 }
1682
1683 /* Read message type, message serial, unique name, object path,
1684 interface and member from the message. */
1685 mtype = dbus_message_get_type (dmessage);
1686 serial =
1687 ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1688 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1689 ? dbus_message_get_reply_serial (dmessage)
1690 : dbus_message_get_serial (dmessage);
1691 uname = dbus_message_get_sender (dmessage);
1692 path = dbus_message_get_path (dmessage);
1693 interface = dbus_message_get_interface (dmessage);
1694 member = dbus_message_get_member (dmessage);
1695
1696 XD_DEBUG_MESSAGE ("Event received: %s %d %s %s %s %s %s",
1697 (mtype == DBUS_MESSAGE_TYPE_INVALID)
1698 ? "DBUS_MESSAGE_TYPE_INVALID"
1699 : (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1700 ? "DBUS_MESSAGE_TYPE_METHOD_CALL"
1701 : (mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1702 ? "DBUS_MESSAGE_TYPE_METHOD_RETURN"
1703 : (mtype == DBUS_MESSAGE_TYPE_ERROR)
1704 ? "DBUS_MESSAGE_TYPE_ERROR"
1705 : "DBUS_MESSAGE_TYPE_SIGNAL",
1706 serial, uname, path, interface, member,
1707 SDATA (format2 ("%s", args, Qnil)));
1708
1709 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1710 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1711 {
1712 /* Search for a registered function of the message. */
1713 key = list2 (bus, make_number (serial));
1714 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1715
1716 /* There shall be exactly one entry. Construct an event. */
1717 if (NILP (value))
1718 goto cleanup;
1719
1720 /* Remove the entry. */
1721 Fremhash (key, Vdbus_registered_objects_table);
1722
1723 /* Construct an event. */
1724 EVENT_INIT (event);
1725 event.kind = DBUS_EVENT;
1726 event.frame_or_window = Qnil;
1727 event.arg = Fcons (value, args);
1728 }
1729
1730 else /* (mtype != DBUS_MESSAGE_TYPE_METHOD_RETURN) */
1731 {
1732 /* Vdbus_registered_objects_table requires non-nil interface and
1733 member. */
1734 if ((interface == NULL) || (member == NULL))
1735 goto cleanup;
1736
1737 /* Search for a registered function of the message. */
1738 key = list3 (bus, build_string (interface), build_string (member));
1739 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1740
1741 /* Loop over the registered functions. Construct an event. */
1742 while (!NILP (value))
1743 {
1744 key = CAR_SAFE (value);
1745 /* key has the structure (UNAME SERVICE PATH HANDLER). */
1746 if (((uname == NULL)
1747 || (NILP (CAR_SAFE (key)))
1748 || (strcmp (uname, SSDATA (CAR_SAFE (key))) == 0))
1749 && ((path == NULL)
1750 || (NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (key)))))
1751 || (strcmp (path,
1752 SSDATA (CAR_SAFE (CDR_SAFE (CDR_SAFE (key)))))
1753 == 0))
1754 && (!NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))))))
1755 {
1756 EVENT_INIT (event);
1757 event.kind = DBUS_EVENT;
1758 event.frame_or_window = Qnil;
1759 event.arg = Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))),
1760 args);
1761 break;
1762 }
1763 value = CDR_SAFE (value);
1764 }
1765
1766 if (NILP (value))
1767 goto cleanup;
1768 }
1769
1770 /* Add type, serial, uname, path, interface and member to the event. */
1771 event.arg = Fcons ((member == NULL ? Qnil : build_string (member)),
1772 event.arg);
1773 event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)),
1774 event.arg);
1775 event.arg = Fcons ((path == NULL ? Qnil : build_string (path)),
1776 event.arg);
1777 event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)),
1778 event.arg);
1779 event.arg = Fcons (make_number (serial), event.arg);
1780 event.arg = Fcons (make_number (mtype), event.arg);
1781
1782 /* Add the bus symbol to the event. */
1783 event.arg = Fcons (bus, event.arg);
1784
1785 /* Store it into the input event queue. */
1786 kbd_buffer_store_event (&event);
1787
1788 XD_DEBUG_MESSAGE ("Event stored: %s",
1789 SDATA (format2 ("%s", event.arg, Qnil)));
1790
1791 /* Cleanup. */
1792 cleanup:
1793 dbus_message_unref (dmessage);
1794
1795 UNGCPRO;
1796 }
1797
1798 /* Read queued incoming messages of the D-Bus BUS.
1799 BUS is either a Lisp symbol, :system or :session, or a string denoting
1800 the bus address. */
1801 static Lisp_Object
1802 xd_read_message (Lisp_Object bus)
1803 {
1804 /* Open a connection to the bus. */
1805 DBusConnection *connection = xd_initialize (bus, TRUE);
1806
1807 /* Non blocking read of the next available message. */
1808 dbus_connection_read_write (connection, 0);
1809
1810 while (dbus_connection_get_dispatch_status (connection)
1811 != DBUS_DISPATCH_COMPLETE)
1812 xd_read_message_1 (connection, bus);
1813 return Qnil;
1814 }
1815
1816 /* Callback called when something is ready to read or write. */
1817 static void
1818 xd_read_queued_messages (int fd, void *data, int for_read)
1819 {
1820 Lisp_Object busp = Vdbus_registered_buses;
1821 Lisp_Object bus = Qnil;
1822
1823 /* Find bus related to fd. */
1824 if (data != NULL)
1825 while (!NILP (busp))
1826 {
1827 if (data == (void*) XHASH (CAR_SAFE (busp)))
1828 bus = CAR_SAFE (busp);
1829 busp = CDR_SAFE (busp);
1830 }
1831
1832 if (NILP(bus))
1833 return;
1834
1835 /* We ignore all Lisp errors during the call. */
1836 xd_in_read_queued_messages = 1;
1837 internal_catch (Qdbus_error, xd_read_message, bus);
1838 xd_in_read_queued_messages = 0;
1839 }
1840
1841 DEFUN ("dbus-register-service", Fdbus_register_service, Sdbus_register_service,
1842 2, MANY, 0,
1843 doc: /* Register known name SERVICE on the D-Bus BUS.
1844
1845 BUS is either a Lisp symbol, `:system' or `:session', or a string
1846 denoting the bus address.
1847
1848 SERVICE is the D-Bus service name that should be registered. It must
1849 be a known name.
1850
1851 FLAGS are keywords, which control how the service name is registered.
1852 The following keywords are recognized:
1853
1854 `:allow-replacement': Allow another service to become the primary
1855 owner if requested.
1856
1857 `:replace-existing': Request to replace the current primary owner.
1858
1859 `:do-not-queue': If we can not become the primary owner do not place
1860 us in the queue.
1861
1862 The function returns a keyword, indicating the result of the
1863 operation. One of the following keywords is returned:
1864
1865 `:primary-owner': Service has become the primary owner of the
1866 requested name.
1867
1868 `:in-queue': Service could not become the primary owner and has been
1869 placed in the queue.
1870
1871 `:exists': Service is already in the queue.
1872
1873 `:already-owner': Service is already the primary owner.
1874
1875 Example:
1876
1877 \(dbus-register-service :session dbus-service-emacs)
1878
1879 => :primary-owner.
1880
1881 \(dbus-register-service
1882 :session "org.freedesktop.TextEditor"
1883 dbus-service-allow-replacement dbus-service-replace-existing)
1884
1885 => :already-owner.
1886
1887 usage: (dbus-register-service BUS SERVICE &rest FLAGS) */)
1888 (size_t nargs, register Lisp_Object *args)
1889 {
1890 Lisp_Object bus, service;
1891 DBusConnection *connection;
1892 size_t i;
1893 unsigned int value;
1894 unsigned int flags = 0;
1895 int result;
1896 DBusError derror;
1897
1898 bus = args[0];
1899 service = args[1];
1900
1901 /* Check parameters. */
1902 CHECK_STRING (service);
1903
1904 /* Process flags. */
1905 for (i = 2; i < nargs; ++i) {
1906 value = ((EQ (args[i], QCdbus_request_name_replace_existing))
1907 ? DBUS_NAME_FLAG_REPLACE_EXISTING
1908 : (EQ (args[i], QCdbus_request_name_allow_replacement))
1909 ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT
1910 : (EQ (args[i], QCdbus_request_name_do_not_queue))
1911 ? DBUS_NAME_FLAG_DO_NOT_QUEUE
1912 : -1);
1913 if (value == -1)
1914 XD_SIGNAL2 (build_string ("Unrecognized name request flag"), args[i]);
1915 flags |= value;
1916 }
1917
1918 /* Open a connection to the bus. */
1919 connection = xd_initialize (bus, TRUE);
1920
1921 /* Request the known name from the bus. */
1922 dbus_error_init (&derror);
1923 result = dbus_bus_request_name (connection, SSDATA (service), flags,
1924 &derror);
1925 if (dbus_error_is_set (&derror))
1926 XD_ERROR (derror);
1927
1928 /* Cleanup. */
1929 dbus_error_free (&derror);
1930
1931 /* Return object. */
1932 switch (result)
1933 {
1934 case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
1935 return QCdbus_request_name_reply_primary_owner;
1936 case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
1937 return QCdbus_request_name_reply_in_queue;
1938 case DBUS_REQUEST_NAME_REPLY_EXISTS:
1939 return QCdbus_request_name_reply_exists;
1940 case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
1941 return QCdbus_request_name_reply_already_owner;
1942 default:
1943 /* This should not happen. */
1944 XD_SIGNAL2 (build_string ("Could not register service"), service);
1945 }
1946 }
1947
1948 DEFUN ("dbus-register-signal", Fdbus_register_signal, Sdbus_register_signal,
1949 6, MANY, 0,
1950 doc: /* Register for signal SIGNAL on the D-Bus BUS.
1951
1952 BUS is either a Lisp symbol, `:system' or `:session', or a string
1953 denoting the bus address.
1954
1955 SERVICE is the D-Bus service name used by the sending D-Bus object.
1956 It can be either a known name or the unique name of the D-Bus object
1957 sending the signal. When SERVICE is nil, related signals from all
1958 D-Bus objects shall be accepted.
1959
1960 PATH is the D-Bus object path SERVICE is registered. It can also be
1961 nil if the path name of incoming signals shall not be checked.
1962
1963 INTERFACE is an interface offered by SERVICE. It must provide SIGNAL.
1964 HANDLER is a Lisp function to be called when the signal is received.
1965 It must accept as arguments the values SIGNAL is sending.
1966
1967 All other arguments ARGS, if specified, must be strings. They stand
1968 for the respective arguments of the signal in their order, and are
1969 used for filtering as well. A nil argument might be used to preserve
1970 the order.
1971
1972 INTERFACE, SIGNAL and HANDLER must not be nil. Example:
1973
1974 \(defun my-signal-handler (device)
1975 (message "Device %s added" device))
1976
1977 \(dbus-register-signal
1978 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/Manager"
1979 "org.freedesktop.Hal.Manager" "DeviceAdded" 'my-signal-handler)
1980
1981 => ((:system "org.freedesktop.Hal.Manager" "DeviceAdded")
1982 ("org.freedesktop.Hal" "/org/freedesktop/Hal/Manager" my-signal-handler))
1983
1984 `dbus-register-signal' returns an object, which can be used in
1985 `dbus-unregister-object' for removing the registration.
1986
1987 usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARGS) */)
1988 (size_t nargs, register Lisp_Object *args)
1989 {
1990 Lisp_Object bus, service, path, interface, signal, handler;
1991 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
1992 Lisp_Object uname, key, key1, value;
1993 DBusConnection *connection;
1994 size_t i;
1995 char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
1996 char x[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
1997 DBusError derror;
1998
1999 /* Check parameters. */
2000 bus = args[0];
2001 service = args[1];
2002 path = args[2];
2003 interface = args[3];
2004 signal = args[4];
2005 handler = args[5];
2006
2007 if (!NILP (service)) CHECK_STRING (service);
2008 if (!NILP (path)) CHECK_STRING (path);
2009 CHECK_STRING (interface);
2010 CHECK_STRING (signal);
2011 if (!FUNCTIONP (handler))
2012 wrong_type_argument (intern ("functionp"), handler);
2013 GCPRO6 (bus, service, path, interface, signal, handler);
2014
2015 /* Retrieve unique name of service. If service is a known name, we
2016 will register for the corresponding unique name, if any. Signals
2017 are sent always with the unique name as sender. Note: the unique
2018 name of "org.freedesktop.DBus" is that string itself. */
2019 if ((STRINGP (service))
2020 && (SBYTES (service) > 0)
2021 && (strcmp (SSDATA (service), DBUS_SERVICE_DBUS) != 0)
2022 && (strncmp (SSDATA (service), ":", 1) != 0))
2023 {
2024 uname = call2 (intern ("dbus-get-name-owner"), bus, service);
2025 /* When there is no unique name, we mark it with an empty
2026 string. */
2027 if (NILP (uname))
2028 uname = empty_unibyte_string;
2029 }
2030 else
2031 uname = service;
2032
2033 /* Create a matching rule if the unique name exists (when no
2034 wildcard). */
2035 if (NILP (uname) || (SBYTES (uname) > 0))
2036 {
2037 /* Open a connection to the bus. */
2038 connection = xd_initialize (bus, TRUE);
2039
2040 /* Create a rule to receive related signals. */
2041 sprintf (rule,
2042 "type='signal',interface='%s',member='%s'",
2043 SDATA (interface),
2044 SDATA (signal));
2045
2046 /* Add unique name and path to the rule if they are non-nil. */
2047 if (!NILP (uname))
2048 {
2049 sprintf (x, ",sender='%s'", SDATA (uname));
2050 strcat (rule, x);
2051 }
2052
2053 if (!NILP (path))
2054 {
2055 sprintf (x, ",path='%s'", SDATA (path));
2056 strcat (rule, x);
2057 }
2058
2059 /* Add arguments to the rule if they are non-nil. */
2060 for (i = 6; i < nargs; ++i)
2061 if (!NILP (args[i]))
2062 {
2063 CHECK_STRING (args[i]);
2064 sprintf (x, ",arg%lu='%s'", (unsigned long) (i-6),
2065 SDATA (args[i]));
2066 strcat (rule, x);
2067 }
2068
2069 /* Add the rule to the bus. */
2070 dbus_error_init (&derror);
2071 dbus_bus_add_match (connection, rule, &derror);
2072 if (dbus_error_is_set (&derror))
2073 {
2074 UNGCPRO;
2075 XD_ERROR (derror);
2076 }
2077
2078 /* Cleanup. */
2079 dbus_error_free (&derror);
2080
2081 XD_DEBUG_MESSAGE ("Matching rule \"%s\" created", rule);
2082 }
2083
2084 /* Create a hash table entry. */
2085 key = list3 (bus, interface, signal);
2086 key1 = list4 (uname, service, path, handler);
2087 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
2088
2089 if (NILP (Fmember (key1, value)))
2090 Fputhash (key, Fcons (key1, value), Vdbus_registered_objects_table);
2091
2092 /* Return object. */
2093 RETURN_UNGCPRO (list2 (key, list3 (service, path, handler)));
2094 }
2095
2096 DEFUN ("dbus-register-method", Fdbus_register_method, Sdbus_register_method,
2097 6, 7, 0,
2098 doc: /* Register for method METHOD on the D-Bus BUS.
2099
2100 BUS is either a Lisp symbol, `:system' or `:session', or a string
2101 denoting the bus address.
2102
2103 SERVICE is the D-Bus service name of the D-Bus object METHOD is
2104 registered for. It must be a known name (See discussion of
2105 DONT-REGISTER-SERVICE below).
2106
2107 PATH is the D-Bus object path SERVICE is registered (See discussion of
2108 DONT-REGISTER-SERVICE below). INTERFACE is the interface offered by
2109 SERVICE. It must provide METHOD. HANDLER is a Lisp function to be
2110 called when a method call is received. It must accept the input
2111 arguments of METHOD. The return value of HANDLER is used for
2112 composing the returning D-Bus message.
2113
2114 When DONT-REGISTER-SERVICE is non-nil, the known name SERVICE is not
2115 registered. This means that other D-Bus clients have no way of
2116 noticing the newly registered method. When interfaces are constructed
2117 incrementally by adding single methods or properties at a time,
2118 DONT-REGISTER-SERVICE can be use to prevent other clients from
2119 discovering the still incomplete interface.*/)
2120 (Lisp_Object bus, Lisp_Object service, Lisp_Object path,
2121 Lisp_Object interface, Lisp_Object method, Lisp_Object handler,
2122 Lisp_Object dont_register_service)
2123 {
2124 Lisp_Object key, key1, value;
2125 Lisp_Object args[2] = { bus, service };
2126
2127 /* Check parameters. */
2128 CHECK_STRING (service);
2129 CHECK_STRING (path);
2130 CHECK_STRING (interface);
2131 CHECK_STRING (method);
2132 if (!FUNCTIONP (handler))
2133 wrong_type_argument (intern ("functionp"), handler);
2134 /* TODO: We must check for a valid service name, otherwise there is
2135 a segmentation fault. */
2136
2137 /* Request the name. */
2138 if (NILP (dont_register_service))
2139 Fdbus_register_service (2, args);
2140
2141 /* Create a hash table entry. We use nil for the unique name,
2142 because the method might be called from anybody. */
2143 key = list3 (bus, interface, method);
2144 key1 = list4 (Qnil, service, path, handler);
2145 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
2146
2147 if (NILP (Fmember (key1, value)))
2148 Fputhash (key, Fcons (key1, value), Vdbus_registered_objects_table);
2149
2150 /* Return object. */
2151 return list2 (key, list3 (service, path, handler));
2152 }
2153
2154 \f
2155 void
2156 syms_of_dbusbind (void)
2157 {
2158
2159 Qdbus_init_bus = intern_c_string ("dbus-init-bus");
2160 staticpro (&Qdbus_init_bus);
2161 defsubr (&Sdbus_init_bus);
2162
2163 Qdbus_close_bus = intern_c_string ("dbus-close-bus");
2164 staticpro (&Qdbus_close_bus);
2165 defsubr (&Sdbus_close_bus);
2166
2167 Qdbus_get_unique_name = intern_c_string ("dbus-get-unique-name");
2168 staticpro (&Qdbus_get_unique_name);
2169 defsubr (&Sdbus_get_unique_name);
2170
2171 Qdbus_call_method = intern_c_string ("dbus-call-method");
2172 staticpro (&Qdbus_call_method);
2173 defsubr (&Sdbus_call_method);
2174
2175 Qdbus_call_method_asynchronously = intern_c_string ("dbus-call-method-asynchronously");
2176 staticpro (&Qdbus_call_method_asynchronously);
2177 defsubr (&Sdbus_call_method_asynchronously);
2178
2179 Qdbus_method_return_internal = intern_c_string ("dbus-method-return-internal");
2180 staticpro (&Qdbus_method_return_internal);
2181 defsubr (&Sdbus_method_return_internal);
2182
2183 Qdbus_method_error_internal = intern_c_string ("dbus-method-error-internal");
2184 staticpro (&Qdbus_method_error_internal);
2185 defsubr (&Sdbus_method_error_internal);
2186
2187 Qdbus_send_signal = intern_c_string ("dbus-send-signal");
2188 staticpro (&Qdbus_send_signal);
2189 defsubr (&Sdbus_send_signal);
2190
2191 Qdbus_register_service = intern_c_string ("dbus-register-service");
2192 staticpro (&Qdbus_register_service);
2193 defsubr (&Sdbus_register_service);
2194
2195 Qdbus_register_signal = intern_c_string ("dbus-register-signal");
2196 staticpro (&Qdbus_register_signal);
2197 defsubr (&Sdbus_register_signal);
2198
2199 Qdbus_register_method = intern_c_string ("dbus-register-method");
2200 staticpro (&Qdbus_register_method);
2201 defsubr (&Sdbus_register_method);
2202
2203 Qdbus_error = intern_c_string ("dbus-error");
2204 staticpro (&Qdbus_error);
2205 Fput (Qdbus_error, Qerror_conditions,
2206 list2 (Qdbus_error, Qerror));
2207 Fput (Qdbus_error, Qerror_message,
2208 make_pure_c_string ("D-Bus error"));
2209
2210 QCdbus_system_bus = intern_c_string (":system");
2211 staticpro (&QCdbus_system_bus);
2212
2213 QCdbus_session_bus = intern_c_string (":session");
2214 staticpro (&QCdbus_session_bus);
2215
2216 QCdbus_request_name_allow_replacement = intern_c_string (":allow-replacement");
2217 staticpro (&QCdbus_request_name_allow_replacement);
2218
2219 QCdbus_request_name_replace_existing = intern_c_string (":replace-existing");
2220 staticpro (&QCdbus_request_name_replace_existing);
2221
2222 QCdbus_request_name_do_not_queue = intern_c_string (":do-not-queue");
2223 staticpro (&QCdbus_request_name_do_not_queue);
2224
2225 QCdbus_request_name_reply_primary_owner = intern_c_string (":primary-owner");
2226 staticpro (&QCdbus_request_name_reply_primary_owner);
2227
2228 QCdbus_request_name_reply_exists = intern_c_string (":exists");
2229 staticpro (&QCdbus_request_name_reply_exists);
2230
2231 QCdbus_request_name_reply_in_queue = intern_c_string (":in-queue");
2232 staticpro (&QCdbus_request_name_reply_in_queue);
2233
2234 QCdbus_request_name_reply_already_owner = intern_c_string (":already-owner");
2235 staticpro (&QCdbus_request_name_reply_already_owner);
2236
2237 QCdbus_timeout = intern_c_string (":timeout");
2238 staticpro (&QCdbus_timeout);
2239
2240 QCdbus_type_byte = intern_c_string (":byte");
2241 staticpro (&QCdbus_type_byte);
2242
2243 QCdbus_type_boolean = intern_c_string (":boolean");
2244 staticpro (&QCdbus_type_boolean);
2245
2246 QCdbus_type_int16 = intern_c_string (":int16");
2247 staticpro (&QCdbus_type_int16);
2248
2249 QCdbus_type_uint16 = intern_c_string (":uint16");
2250 staticpro (&QCdbus_type_uint16);
2251
2252 QCdbus_type_int32 = intern_c_string (":int32");
2253 staticpro (&QCdbus_type_int32);
2254
2255 QCdbus_type_uint32 = intern_c_string (":uint32");
2256 staticpro (&QCdbus_type_uint32);
2257
2258 QCdbus_type_int64 = intern_c_string (":int64");
2259 staticpro (&QCdbus_type_int64);
2260
2261 QCdbus_type_uint64 = intern_c_string (":uint64");
2262 staticpro (&QCdbus_type_uint64);
2263
2264 QCdbus_type_double = intern_c_string (":double");
2265 staticpro (&QCdbus_type_double);
2266
2267 QCdbus_type_string = intern_c_string (":string");
2268 staticpro (&QCdbus_type_string);
2269
2270 QCdbus_type_object_path = intern_c_string (":object-path");
2271 staticpro (&QCdbus_type_object_path);
2272
2273 QCdbus_type_signature = intern_c_string (":signature");
2274 staticpro (&QCdbus_type_signature);
2275
2276 #ifdef DBUS_TYPE_UNIX_FD
2277 QCdbus_type_unix_fd = intern_c_string (":unix-fd");
2278 staticpro (&QCdbus_type_unix_fd);
2279 #endif
2280
2281 QCdbus_type_array = intern_c_string (":array");
2282 staticpro (&QCdbus_type_array);
2283
2284 QCdbus_type_variant = intern_c_string (":variant");
2285 staticpro (&QCdbus_type_variant);
2286
2287 QCdbus_type_struct = intern_c_string (":struct");
2288 staticpro (&QCdbus_type_struct);
2289
2290 QCdbus_type_dict_entry = intern_c_string (":dict-entry");
2291 staticpro (&QCdbus_type_dict_entry);
2292
2293 DEFVAR_LISP ("dbus-registered-buses",
2294 Vdbus_registered_buses,
2295 doc: /* List of D-Bus buses we are polling for messages. */);
2296 Vdbus_registered_buses = Qnil;
2297
2298 DEFVAR_LISP ("dbus-registered-objects-table",
2299 Vdbus_registered_objects_table,
2300 doc: /* Hash table of registered functions for D-Bus.
2301
2302 There are two different uses of the hash table: for accessing
2303 registered interfaces properties, targeted by signals or method calls,
2304 and for calling handlers in case of non-blocking method call returns.
2305
2306 In the first case, the key in the hash table is the list (BUS
2307 INTERFACE MEMBER). BUS is either a Lisp symbol, `:system' or
2308 `:session', or a string denoting the bus address. INTERFACE is a
2309 string which denotes a D-Bus interface, and MEMBER, also a string, is
2310 either a method, a signal or a property INTERFACE is offering. All
2311 arguments but BUS must not be nil.
2312
2313 The value in the hash table is a list of quadruple lists
2314 \((UNAME SERVICE PATH OBJECT) (UNAME SERVICE PATH OBJECT) ...).
2315 SERVICE is the service name as registered, UNAME is the corresponding
2316 unique name. In case of registered methods and properties, UNAME is
2317 nil. PATH is the object path of the sending object. All of them can
2318 be nil, which means a wildcard then. OBJECT is either the handler to
2319 be called when a D-Bus message, which matches the key criteria,
2320 arrives (methods and signals), or a cons cell containing the value of
2321 the property.
2322
2323 In the second case, the key in the hash table is the list (BUS
2324 SERIAL). BUS is either a Lisp symbol, `:system' or `:session', or a
2325 string denoting the bus address. SERIAL is the serial number of the
2326 non-blocking method call, a reply is expected. Both arguments must
2327 not be nil. The value in the hash table is HANDLER, the function to
2328 be called when the D-Bus reply message arrives. */);
2329 {
2330 Lisp_Object args[2];
2331 args[0] = QCtest;
2332 args[1] = Qequal;
2333 Vdbus_registered_objects_table = Fmake_hash_table (2, args);
2334 }
2335
2336 DEFVAR_LISP ("dbus-debug", Vdbus_debug,
2337 doc: /* If non-nil, debug messages of D-Bus bindings are raised. */);
2338 #ifdef DBUS_DEBUG
2339 Vdbus_debug = Qt;
2340 /* We can also set environment variable DBUS_VERBOSE=1 in order to
2341 see more traces. This requires libdbus-1 to be configured with
2342 --enable-verbose-mode. */
2343 #else
2344 Vdbus_debug = Qnil;
2345 #endif
2346
2347 Fprovide (intern_c_string ("dbusbind"), Qnil);
2348
2349 }
2350
2351 #endif /* HAVE_DBUS */