Reverse 2009-12-03T16:02:10Z!acm@muc.de "Enhance `c-parse-state' to run efficiently in
[emacs.git] / src / dbusbind.c
blob5cad182b525e4f3ee3f00be2fb314187d4809de2
1 /* Elisp bindings for D-Bus.
2 Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
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.
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.
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/>. */
19 #include "config.h"
21 #ifdef HAVE_DBUS
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <dbus/dbus.h>
25 #include <setjmp.h>
26 #include "lisp.h"
27 #include "frame.h"
28 #include "termhooks.h"
29 #include "keyboard.h"
32 /* Subroutines. */
33 Lisp_Object Qdbus_init_bus;
34 Lisp_Object Qdbus_get_unique_name;
35 Lisp_Object Qdbus_call_method;
36 Lisp_Object Qdbus_call_method_asynchronously;
37 Lisp_Object Qdbus_method_return_internal;
38 Lisp_Object Qdbus_method_error_internal;
39 Lisp_Object Qdbus_send_signal;
40 Lisp_Object Qdbus_register_signal;
41 Lisp_Object Qdbus_register_method;
43 /* D-Bus error symbol. */
44 Lisp_Object Qdbus_error;
46 /* Lisp symbols of the system and session buses. */
47 Lisp_Object QCdbus_system_bus, QCdbus_session_bus;
49 /* Lisp symbol for method call timeout. */
50 Lisp_Object QCdbus_timeout;
52 /* Lisp symbols of D-Bus types. */
53 Lisp_Object QCdbus_type_byte, QCdbus_type_boolean;
54 Lisp_Object QCdbus_type_int16, QCdbus_type_uint16;
55 Lisp_Object QCdbus_type_int32, QCdbus_type_uint32;
56 Lisp_Object QCdbus_type_int64, QCdbus_type_uint64;
57 Lisp_Object QCdbus_type_double, QCdbus_type_string;
58 Lisp_Object QCdbus_type_object_path, QCdbus_type_signature;
59 Lisp_Object QCdbus_type_array, QCdbus_type_variant;
60 Lisp_Object QCdbus_type_struct, QCdbus_type_dict_entry;
62 /* Hash table which keeps function definitions. */
63 Lisp_Object Vdbus_registered_objects_table;
65 /* Whether to debug D-Bus. */
66 Lisp_Object Vdbus_debug;
68 /* Whether we are reading a D-Bus event. */
69 int xd_in_read_queued_messages = 0;
72 /* We use "xd_" and "XD_" as prefix for all internal symbols, because
73 we don't want to poison other namespaces with "dbus_". */
75 /* Raise a signal. If we are reading events, we cannot signal; we
76 throw to xd_read_queued_messages then. */
77 #define XD_SIGNAL1(arg) \
78 do { \
79 if (xd_in_read_queued_messages) \
80 Fthrow (Qdbus_error, Qnil); \
81 else \
82 xsignal1 (Qdbus_error, arg); \
83 } while (0)
85 #define XD_SIGNAL2(arg1, arg2) \
86 do { \
87 if (xd_in_read_queued_messages) \
88 Fthrow (Qdbus_error, Qnil); \
89 else \
90 xsignal2 (Qdbus_error, arg1, arg2); \
91 } while (0)
93 #define XD_SIGNAL3(arg1, arg2, arg3) \
94 do { \
95 if (xd_in_read_queued_messages) \
96 Fthrow (Qdbus_error, Qnil); \
97 else \
98 xsignal3 (Qdbus_error, arg1, arg2, arg3); \
99 } while (0)
101 /* Raise a Lisp error from a D-Bus ERROR. */
102 #define XD_ERROR(error) \
103 do { \
104 char s[1024]; \
105 strncpy (s, error.message, 1023); \
106 dbus_error_free (&error); \
107 /* Remove the trailing newline. */ \
108 if (strchr (s, '\n') != NULL) \
109 s[strlen (s) - 1] = '\0'; \
110 XD_SIGNAL1 (build_string (s)); \
111 } while (0)
113 /* Macros for debugging. In order to enable them, build with
114 "make MYCPPFLAGS='-DDBUS_DEBUG -Wall'". */
115 #ifdef DBUS_DEBUG
116 #define XD_DEBUG_MESSAGE(...) \
117 do { \
118 char s[1024]; \
119 snprintf (s, 1023, __VA_ARGS__); \
120 printf ("%s: %s\n", __func__, s); \
121 message ("%s: %s", __func__, s); \
122 } while (0)
123 #define XD_DEBUG_VALID_LISP_OBJECT_P(object) \
124 do { \
125 if (!valid_lisp_object_p (object)) \
127 XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__); \
128 XD_SIGNAL1 (build_string ("Assertion failure")); \
130 } while (0)
132 #else /* !DBUS_DEBUG */
133 #define XD_DEBUG_MESSAGE(...) \
134 do { \
135 if (!NILP (Vdbus_debug)) \
137 char s[1024]; \
138 snprintf (s, 1023, __VA_ARGS__); \
139 message ("%s: %s", __func__, s); \
141 } while (0)
142 #define XD_DEBUG_VALID_LISP_OBJECT_P(object)
143 #endif
145 /* Check whether TYPE is a basic DBusType. */
146 #define XD_BASIC_DBUS_TYPE(type) \
147 ((type == DBUS_TYPE_BYTE) \
148 || (type == DBUS_TYPE_BOOLEAN) \
149 || (type == DBUS_TYPE_INT16) \
150 || (type == DBUS_TYPE_UINT16) \
151 || (type == DBUS_TYPE_INT32) \
152 || (type == DBUS_TYPE_UINT32) \
153 || (type == DBUS_TYPE_INT64) \
154 || (type == DBUS_TYPE_UINT64) \
155 || (type == DBUS_TYPE_DOUBLE) \
156 || (type == DBUS_TYPE_STRING) \
157 || (type == DBUS_TYPE_OBJECT_PATH) \
158 || (type == DBUS_TYPE_SIGNATURE))
160 /* This was a macro. On Solaris 2.11 it was said to compile for
161 hours, when optimzation is enabled. So we have transferred it into
162 a function. */
163 /* Determine the DBusType of a given Lisp symbol. OBJECT must be one
164 of the predefined D-Bus type symbols. */
165 static int
166 xd_symbol_to_dbus_type (object)
167 Lisp_Object object;
169 return
170 ((EQ (object, QCdbus_type_byte)) ? DBUS_TYPE_BYTE
171 : (EQ (object, QCdbus_type_boolean)) ? DBUS_TYPE_BOOLEAN
172 : (EQ (object, QCdbus_type_int16)) ? DBUS_TYPE_INT16
173 : (EQ (object, QCdbus_type_uint16)) ? DBUS_TYPE_UINT16
174 : (EQ (object, QCdbus_type_int32)) ? DBUS_TYPE_INT32
175 : (EQ (object, QCdbus_type_uint32)) ? DBUS_TYPE_UINT32
176 : (EQ (object, QCdbus_type_int64)) ? DBUS_TYPE_INT64
177 : (EQ (object, QCdbus_type_uint64)) ? DBUS_TYPE_UINT64
178 : (EQ (object, QCdbus_type_double)) ? DBUS_TYPE_DOUBLE
179 : (EQ (object, QCdbus_type_string)) ? DBUS_TYPE_STRING
180 : (EQ (object, QCdbus_type_object_path)) ? DBUS_TYPE_OBJECT_PATH
181 : (EQ (object, QCdbus_type_signature)) ? DBUS_TYPE_SIGNATURE
182 : (EQ (object, QCdbus_type_array)) ? DBUS_TYPE_ARRAY
183 : (EQ (object, QCdbus_type_variant)) ? DBUS_TYPE_VARIANT
184 : (EQ (object, QCdbus_type_struct)) ? DBUS_TYPE_STRUCT
185 : (EQ (object, QCdbus_type_dict_entry)) ? DBUS_TYPE_DICT_ENTRY
186 : DBUS_TYPE_INVALID);
189 /* Check whether a Lisp symbol is a predefined D-Bus type symbol. */
190 #define XD_DBUS_TYPE_P(object) \
191 (SYMBOLP (object) && ((xd_symbol_to_dbus_type (object) != DBUS_TYPE_INVALID)))
193 /* Determine the DBusType of a given Lisp OBJECT. It is used to
194 convert Lisp objects, being arguments of `dbus-call-method' or
195 `dbus-send-signal', into corresponding C values appended as
196 arguments to a D-Bus message. */
197 #define XD_OBJECT_TO_DBUS_TYPE(object) \
198 ((EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN \
199 : (NATNUMP (object)) ? DBUS_TYPE_UINT32 \
200 : (INTEGERP (object)) ? DBUS_TYPE_INT32 \
201 : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \
202 : (STRINGP (object)) ? DBUS_TYPE_STRING \
203 : (XD_DBUS_TYPE_P (object)) ? xd_symbol_to_dbus_type (object) \
204 : (CONSP (object)) \
205 ? ((XD_DBUS_TYPE_P (CAR_SAFE (object))) \
206 ? ((XD_BASIC_DBUS_TYPE (xd_symbol_to_dbus_type (CAR_SAFE (object)))) \
207 ? DBUS_TYPE_ARRAY \
208 : xd_symbol_to_dbus_type (CAR_SAFE (object))) \
209 : DBUS_TYPE_ARRAY) \
210 : DBUS_TYPE_INVALID)
212 /* Return a list pointer which does not have a Lisp symbol as car. */
213 #define XD_NEXT_VALUE(object) \
214 ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object)
216 /* Compute SIGNATURE of OBJECT. It must have a form that it can be
217 used in dbus_message_iter_open_container. DTYPE is the DBusType
218 the object is related to. It is passed as argument, because it
219 cannot be detected in basic type objects, when they are preceded by
220 a type symbol. PARENT_TYPE is the DBusType of a container this
221 signature is embedded, or DBUS_TYPE_INVALID. It is needed for the
222 check that DBUS_TYPE_DICT_ENTRY occurs only as array element. */
223 static void
224 xd_signature (signature, dtype, parent_type, object)
225 char *signature;
226 unsigned int dtype, parent_type;
227 Lisp_Object object;
229 unsigned int subtype;
230 Lisp_Object elt;
231 char x[DBUS_MAXIMUM_SIGNATURE_LENGTH];
233 elt = object;
235 switch (dtype)
237 case DBUS_TYPE_BYTE:
238 case DBUS_TYPE_UINT16:
239 case DBUS_TYPE_UINT32:
240 case DBUS_TYPE_UINT64:
241 CHECK_NATNUM (object);
242 sprintf (signature, "%c", dtype);
243 break;
245 case DBUS_TYPE_BOOLEAN:
246 if (!EQ (object, Qt) && !EQ (object, Qnil))
247 wrong_type_argument (intern ("booleanp"), object);
248 sprintf (signature, "%c", dtype);
249 break;
251 case DBUS_TYPE_INT16:
252 case DBUS_TYPE_INT32:
253 case DBUS_TYPE_INT64:
254 CHECK_NUMBER (object);
255 sprintf (signature, "%c", dtype);
256 break;
258 case DBUS_TYPE_DOUBLE:
259 CHECK_FLOAT (object);
260 sprintf (signature, "%c", dtype);
261 break;
263 case DBUS_TYPE_STRING:
264 case DBUS_TYPE_OBJECT_PATH:
265 case DBUS_TYPE_SIGNATURE:
266 CHECK_STRING (object);
267 sprintf (signature, "%c", dtype);
268 break;
270 case DBUS_TYPE_ARRAY:
271 /* Check that all list elements have the same D-Bus type. For
272 complex element types, we just check the container type, not
273 the whole element's signature. */
274 CHECK_CONS (object);
276 /* Type symbol is optional. */
277 if (EQ (QCdbus_type_array, CAR_SAFE (elt)))
278 elt = XD_NEXT_VALUE (elt);
280 /* If the array is empty, DBUS_TYPE_STRING is the default
281 element type. */
282 if (NILP (elt))
284 subtype = DBUS_TYPE_STRING;
285 strcpy (x, DBUS_TYPE_STRING_AS_STRING);
287 else
289 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
290 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
293 /* If the element type is DBUS_TYPE_SIGNATURE, and this is the
294 only element, the value of this element is used as he array's
295 element signature. */
296 if ((subtype == DBUS_TYPE_SIGNATURE)
297 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt)))
298 && NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
299 strcpy (x, SDATA (CAR_SAFE (XD_NEXT_VALUE (elt))));
301 while (!NILP (elt))
303 if (subtype != XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)))
304 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (elt));
305 elt = CDR_SAFE (XD_NEXT_VALUE (elt));
308 sprintf (signature, "%c%s", dtype, x);
309 break;
311 case DBUS_TYPE_VARIANT:
312 /* Check that there is exactly one list element. */
313 CHECK_CONS (object);
315 elt = XD_NEXT_VALUE (elt);
316 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
317 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
319 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
320 wrong_type_argument (intern ("D-Bus"),
321 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt))));
323 sprintf (signature, "%c", dtype);
324 break;
326 case DBUS_TYPE_STRUCT:
327 /* A struct list might contain any number of elements with
328 different types. No further check needed. */
329 CHECK_CONS (object);
331 elt = XD_NEXT_VALUE (elt);
333 /* Compose the signature from the elements. It is enclosed by
334 parentheses. */
335 sprintf (signature, "%c", DBUS_STRUCT_BEGIN_CHAR );
336 while (!NILP (elt))
338 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
339 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
340 strcat (signature, x);
341 elt = CDR_SAFE (XD_NEXT_VALUE (elt));
343 strcat (signature, DBUS_STRUCT_END_CHAR_AS_STRING);
344 break;
346 case DBUS_TYPE_DICT_ENTRY:
347 /* Check that there are exactly two list elements, and the first
348 one is of basic type. The dictionary entry itself must be an
349 element of an array. */
350 CHECK_CONS (object);
352 /* Check the parent object type. */
353 if (parent_type != DBUS_TYPE_ARRAY)
354 wrong_type_argument (intern ("D-Bus"), object);
356 /* Compose the signature from the elements. It is enclosed by
357 curly braces. */
358 sprintf (signature, "%c", DBUS_DICT_ENTRY_BEGIN_CHAR);
360 /* First element. */
361 elt = XD_NEXT_VALUE (elt);
362 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
363 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
364 strcat (signature, x);
366 if (!XD_BASIC_DBUS_TYPE (subtype))
367 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt)));
369 /* Second element. */
370 elt = CDR_SAFE (XD_NEXT_VALUE (elt));
371 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
372 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
373 strcat (signature, x);
375 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
376 wrong_type_argument (intern ("D-Bus"),
377 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt))));
379 /* Closing signature. */
380 strcat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
381 break;
383 default:
384 wrong_type_argument (intern ("D-Bus"), object);
387 XD_DEBUG_MESSAGE ("%s", signature);
390 /* Append C value, extracted from Lisp OBJECT, to iteration ITER.
391 DTYPE must be a valid DBusType. It is used to convert Lisp
392 objects, being arguments of `dbus-call-method' or
393 `dbus-send-signal', into corresponding C values appended as
394 arguments to a D-Bus message. */
395 static void
396 xd_append_arg (dtype, object, iter)
397 unsigned int dtype;
398 Lisp_Object object;
399 DBusMessageIter *iter;
401 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
402 DBusMessageIter subiter;
404 if (XD_BASIC_DBUS_TYPE (dtype))
405 switch (dtype)
407 case DBUS_TYPE_BYTE:
409 unsigned char val = XUINT (object) & 0xFF;
410 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
411 if (!dbus_message_iter_append_basic (iter, dtype, &val))
412 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
413 return;
416 case DBUS_TYPE_BOOLEAN:
418 dbus_bool_t val = (NILP (object)) ? FALSE : TRUE;
419 XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
420 if (!dbus_message_iter_append_basic (iter, dtype, &val))
421 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
422 return;
425 case DBUS_TYPE_INT16:
427 dbus_int16_t val = XINT (object);
428 XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
429 if (!dbus_message_iter_append_basic (iter, dtype, &val))
430 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
431 return;
434 case DBUS_TYPE_UINT16:
436 dbus_uint16_t val = XUINT (object);
437 XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val);
438 if (!dbus_message_iter_append_basic (iter, dtype, &val))
439 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
440 return;
443 case DBUS_TYPE_INT32:
445 dbus_int32_t val = XINT (object);
446 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
447 if (!dbus_message_iter_append_basic (iter, dtype, &val))
448 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
449 return;
452 case DBUS_TYPE_UINT32:
454 dbus_uint32_t val = XUINT (object);
455 XD_DEBUG_MESSAGE ("%c %u", dtype, val);
456 if (!dbus_message_iter_append_basic (iter, dtype, &val))
457 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
458 return;
461 case DBUS_TYPE_INT64:
463 dbus_int64_t val = XINT (object);
464 XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
465 if (!dbus_message_iter_append_basic (iter, dtype, &val))
466 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
467 return;
470 case DBUS_TYPE_UINT64:
472 dbus_uint64_t val = XUINT (object);
473 XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val);
474 if (!dbus_message_iter_append_basic (iter, dtype, &val))
475 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
476 return;
479 case DBUS_TYPE_DOUBLE:
481 double val = XFLOAT_DATA (object);
482 XD_DEBUG_MESSAGE ("%c %f", dtype, val);
483 if (!dbus_message_iter_append_basic (iter, dtype, &val))
484 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
485 return;
488 case DBUS_TYPE_STRING:
489 case DBUS_TYPE_OBJECT_PATH:
490 case DBUS_TYPE_SIGNATURE:
492 char *val = SDATA (Fstring_make_unibyte (object));
493 XD_DEBUG_MESSAGE ("%c %s", dtype, val);
494 if (!dbus_message_iter_append_basic (iter, dtype, &val))
495 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
496 return;
500 else /* Compound types. */
503 /* All compound types except array have a type symbol. For
504 array, it is optional. Skip it. */
505 if (!XD_BASIC_DBUS_TYPE (XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object))))
506 object = XD_NEXT_VALUE (object);
508 /* Open new subiteration. */
509 switch (dtype)
511 case DBUS_TYPE_ARRAY:
512 /* An array has only elements of the same type. So it is
513 sufficient to check the first element's signature
514 only. */
516 if (NILP (object))
517 /* If the array is empty, DBUS_TYPE_STRING is the default
518 element type. */
519 strcpy (signature, DBUS_TYPE_STRING_AS_STRING);
521 else
522 /* If the element type is DBUS_TYPE_SIGNATURE, and this is
523 the only element, the value of this element is used as
524 the array's element signature. */
525 if ((XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object))
526 == DBUS_TYPE_SIGNATURE)
527 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object)))
528 && NILP (CDR_SAFE (XD_NEXT_VALUE (object))))
530 strcpy (signature, SDATA (CAR_SAFE (XD_NEXT_VALUE (object))));
531 object = CDR_SAFE (XD_NEXT_VALUE (object));
534 else
535 xd_signature (signature,
536 XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)),
537 dtype, CAR_SAFE (XD_NEXT_VALUE (object)));
539 XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature,
540 SDATA (format2 ("%s", object, Qnil)));
541 if (!dbus_message_iter_open_container (iter, dtype,
542 signature, &subiter))
543 XD_SIGNAL3 (build_string ("Cannot open container"),
544 make_number (dtype), build_string (signature));
545 break;
547 case DBUS_TYPE_VARIANT:
548 /* A variant has just one element. */
549 xd_signature (signature, XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)),
550 dtype, CAR_SAFE (XD_NEXT_VALUE (object)));
552 XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature,
553 SDATA (format2 ("%s", object, Qnil)));
554 if (!dbus_message_iter_open_container (iter, dtype,
555 signature, &subiter))
556 XD_SIGNAL3 (build_string ("Cannot open container"),
557 make_number (dtype), build_string (signature));
558 break;
560 case DBUS_TYPE_STRUCT:
561 case DBUS_TYPE_DICT_ENTRY:
562 /* These containers do not require a signature. */
563 XD_DEBUG_MESSAGE ("%c %s", dtype,
564 SDATA (format2 ("%s", object, Qnil)));
565 if (!dbus_message_iter_open_container (iter, dtype, NULL, &subiter))
566 XD_SIGNAL2 (build_string ("Cannot open container"),
567 make_number (dtype));
568 break;
571 /* Loop over list elements. */
572 while (!NILP (object))
574 dtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object));
575 object = XD_NEXT_VALUE (object);
577 xd_append_arg (dtype, CAR_SAFE (object), &subiter);
579 object = CDR_SAFE (object);
582 /* Close the subiteration. */
583 if (!dbus_message_iter_close_container (iter, &subiter))
584 XD_SIGNAL2 (build_string ("Cannot close container"),
585 make_number (dtype));
589 /* Retrieve C value from a DBusMessageIter structure ITER, and return
590 a converted Lisp object. The type DTYPE of the argument of the
591 D-Bus message must be a valid DBusType. Compound D-Bus types
592 result always in a Lisp list. */
593 static Lisp_Object
594 xd_retrieve_arg (dtype, iter)
595 unsigned int dtype;
596 DBusMessageIter *iter;
599 switch (dtype)
601 case DBUS_TYPE_BYTE:
603 unsigned int val;
604 dbus_message_iter_get_basic (iter, &val);
605 val = val & 0xFF;
606 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
607 return make_number (val);
610 case DBUS_TYPE_BOOLEAN:
612 dbus_bool_t val;
613 dbus_message_iter_get_basic (iter, &val);
614 XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
615 return (val == FALSE) ? Qnil : Qt;
618 case DBUS_TYPE_INT16:
620 dbus_int16_t val;
621 dbus_message_iter_get_basic (iter, &val);
622 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
623 return make_number (val);
626 case DBUS_TYPE_UINT16:
628 dbus_uint16_t val;
629 dbus_message_iter_get_basic (iter, &val);
630 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
631 return make_number (val);
634 case DBUS_TYPE_INT32:
636 dbus_int32_t val;
637 dbus_message_iter_get_basic (iter, &val);
638 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
639 return make_fixnum_or_float (val);
642 case DBUS_TYPE_UINT32:
644 dbus_uint32_t val;
645 dbus_message_iter_get_basic (iter, &val);
646 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
647 return make_fixnum_or_float (val);
650 case DBUS_TYPE_INT64:
652 dbus_int64_t val;
653 dbus_message_iter_get_basic (iter, &val);
654 XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
655 return make_fixnum_or_float (val);
658 case DBUS_TYPE_UINT64:
660 dbus_uint64_t val;
661 dbus_message_iter_get_basic (iter, &val);
662 XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
663 return make_fixnum_or_float (val);
666 case DBUS_TYPE_DOUBLE:
668 double val;
669 dbus_message_iter_get_basic (iter, &val);
670 XD_DEBUG_MESSAGE ("%c %f", dtype, val);
671 return make_float (val);
674 case DBUS_TYPE_STRING:
675 case DBUS_TYPE_OBJECT_PATH:
676 case DBUS_TYPE_SIGNATURE:
678 char *val;
679 dbus_message_iter_get_basic (iter, &val);
680 XD_DEBUG_MESSAGE ("%c %s", dtype, val);
681 return build_string (val);
684 case DBUS_TYPE_ARRAY:
685 case DBUS_TYPE_VARIANT:
686 case DBUS_TYPE_STRUCT:
687 case DBUS_TYPE_DICT_ENTRY:
689 Lisp_Object result;
690 struct gcpro gcpro1;
691 DBusMessageIter subiter;
692 int subtype;
693 result = Qnil;
694 GCPRO1 (result);
695 dbus_message_iter_recurse (iter, &subiter);
696 while ((subtype = dbus_message_iter_get_arg_type (&subiter))
697 != DBUS_TYPE_INVALID)
699 result = Fcons (xd_retrieve_arg (subtype, &subiter), result);
700 dbus_message_iter_next (&subiter);
702 XD_DEBUG_MESSAGE ("%c %s", dtype, SDATA (format2 ("%s", result, Qnil)));
703 RETURN_UNGCPRO (Fnreverse (result));
706 default:
707 XD_DEBUG_MESSAGE ("DBusType '%c' not supported", dtype);
708 return Qnil;
712 /* Initialize D-Bus connection. BUS is a Lisp symbol, either :system
713 or :session. It tells which D-Bus to be initialized. */
714 static DBusConnection *
715 xd_initialize (bus)
716 Lisp_Object bus;
718 DBusConnection *connection;
719 DBusError derror;
721 /* Parameter check. */
722 CHECK_SYMBOL (bus);
723 if (!(EQ (bus, QCdbus_system_bus) || EQ (bus, QCdbus_session_bus)))
724 XD_SIGNAL2 (build_string ("Wrong bus name"), bus);
726 /* We do not want to have an autolaunch for the session bus. */
727 if (EQ (bus, QCdbus_session_bus)
728 && getenv ("DBUS_SESSION_BUS_ADDRESS") == NULL)
729 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
731 /* Open a connection to the bus. */
732 dbus_error_init (&derror);
734 if (EQ (bus, QCdbus_system_bus))
735 connection = dbus_bus_get (DBUS_BUS_SYSTEM, &derror);
736 else
737 connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
739 if (dbus_error_is_set (&derror))
740 XD_ERROR (derror);
742 if (connection == NULL)
743 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
745 /* Cleanup. */
746 dbus_error_free (&derror);
748 /* Return the result. */
749 return connection;
753 /* Add connection file descriptor to input_wait_mask, in order to
754 let select() detect, whether a new message has been arrived. */
755 dbus_bool_t
756 xd_add_watch (watch, data)
757 DBusWatch *watch;
758 void *data;
760 /* We check only for incoming data. */
761 if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE)
763 #if HAVE_DBUS_WATCH_GET_UNIX_FD
764 /* TODO: Reverse these on Win32, which prefers the opposite. */
765 int fd = dbus_watch_get_unix_fd(watch);
766 if (fd == -1)
767 fd = dbus_watch_get_socket(watch);
768 #else
769 int fd = dbus_watch_get_fd(watch);
770 #endif
771 XD_DEBUG_MESSAGE ("fd %d", fd);
773 if (fd == -1)
774 return FALSE;
776 /* Add the file descriptor to input_wait_mask. */
777 add_keyboard_wait_descriptor (fd);
780 /* Return. */
781 return TRUE;
784 /* Remove connection file descriptor from input_wait_mask. DATA is
785 the used bus, either QCdbus_system_bus or QCdbus_session_bus. */
786 void
787 xd_remove_watch (watch, data)
788 DBusWatch *watch;
789 void *data;
791 /* We check only for incoming data. */
792 if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE)
794 #if HAVE_DBUS_WATCH_GET_UNIX_FD
795 /* TODO: Reverse these on Win32, which prefers the opposite. */
796 int fd = dbus_watch_get_unix_fd(watch);
797 if (fd == -1)
798 fd = dbus_watch_get_socket(watch);
799 #else
800 int fd = dbus_watch_get_fd(watch);
801 #endif
802 XD_DEBUG_MESSAGE ("fd %d", fd);
804 if (fd == -1)
805 return;
807 /* Unset session environment. */
808 if ((data != NULL) && (data == (void*) XHASH (QCdbus_session_bus)))
810 XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
811 unsetenv ("DBUS_SESSION_BUS_ADDRESS");
814 /* Remove the file descriptor from input_wait_mask. */
815 delete_keyboard_wait_descriptor (fd);
818 /* Return. */
819 return;
822 DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0,
823 doc: /* Initialize connection to D-Bus BUS.
824 This is an internal function, it shall not be used outside dbus.el. */)
825 (bus)
826 Lisp_Object bus;
828 DBusConnection *connection;
830 /* Check parameters. */
831 CHECK_SYMBOL (bus);
833 /* Open a connection to the bus. */
834 connection = xd_initialize (bus);
836 /* Add the watch functions. We pass also the bus as data, in order
837 to distinguish between the busses in xd_remove_watch. */
838 if (!dbus_connection_set_watch_functions (connection,
839 xd_add_watch,
840 xd_remove_watch,
841 NULL, (void*) XHASH (bus), NULL))
842 XD_SIGNAL1 (build_string ("Cannot add watch functions"));
844 /* Return. */
845 return Qnil;
848 DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name,
849 1, 1, 0,
850 doc: /* Return the unique name of Emacs registered at D-Bus BUS. */)
851 (bus)
852 Lisp_Object bus;
854 DBusConnection *connection;
855 const char *name;
857 /* Check parameters. */
858 CHECK_SYMBOL (bus);
860 /* Open a connection to the bus. */
861 connection = xd_initialize (bus);
863 /* Request the name. */
864 name = dbus_bus_get_unique_name (connection);
865 if (name == NULL)
866 XD_SIGNAL1 (build_string ("No unique name available"));
868 /* Return. */
869 return build_string (name);
872 DEFUN ("dbus-call-method", Fdbus_call_method, Sdbus_call_method, 5, MANY, 0,
873 doc: /* Call METHOD on the D-Bus BUS.
875 BUS is either the symbol `:system' or the symbol `:session'.
877 SERVICE is the D-Bus service name to be used. PATH is the D-Bus
878 object path SERVICE is registered at. INTERFACE is an interface
879 offered by SERVICE. It must provide METHOD.
881 If the parameter `:timeout' is given, the following integer TIMEOUT
882 specifies the maximum number of milliseconds the method call must
883 return. The default value is 25,000. If the method call doesn't
884 return in time, a D-Bus error is raised.
886 All other arguments ARGS are passed to METHOD as arguments. They are
887 converted into D-Bus types via the following rules:
889 t and nil => DBUS_TYPE_BOOLEAN
890 number => DBUS_TYPE_UINT32
891 integer => DBUS_TYPE_INT32
892 float => DBUS_TYPE_DOUBLE
893 string => DBUS_TYPE_STRING
894 list => DBUS_TYPE_ARRAY
896 All arguments can be preceded by a type symbol. For details about
897 type symbols, see Info node `(dbus)Type Conversion'.
899 `dbus-call-method' returns the resulting values of METHOD as a list of
900 Lisp objects. The type conversion happens the other direction as for
901 input arguments. It follows the mapping rules:
903 DBUS_TYPE_BOOLEAN => t or nil
904 DBUS_TYPE_BYTE => number
905 DBUS_TYPE_UINT16 => number
906 DBUS_TYPE_INT16 => integer
907 DBUS_TYPE_UINT32 => number or float
908 DBUS_TYPE_INT32 => integer or float
909 DBUS_TYPE_UINT64 => number or float
910 DBUS_TYPE_INT64 => integer or float
911 DBUS_TYPE_DOUBLE => float
912 DBUS_TYPE_STRING => string
913 DBUS_TYPE_OBJECT_PATH => string
914 DBUS_TYPE_SIGNATURE => string
915 DBUS_TYPE_ARRAY => list
916 DBUS_TYPE_VARIANT => list
917 DBUS_TYPE_STRUCT => list
918 DBUS_TYPE_DICT_ENTRY => list
920 Example:
922 \(dbus-call-method
923 :session "org.gnome.seahorse" "/org/gnome/seahorse/keys/openpgp"
924 "org.gnome.seahorse.Keys" "GetKeyField"
925 "openpgp:657984B8C7A966DD" "simple-name")
927 => (t ("Philip R. Zimmermann"))
929 If the result of the METHOD call is just one value, the converted Lisp
930 object is returned instead of a list containing this single Lisp object.
932 \(dbus-call-method
933 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer"
934 "org.freedesktop.Hal.Device" "GetPropertyString"
935 "system.kernel.machine")
937 => "i686"
939 usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &optional :timeout TIMEOUT &rest ARGS) */)
940 (nargs, args)
941 int nargs;
942 register Lisp_Object *args;
944 Lisp_Object bus, service, path, interface, method;
945 Lisp_Object result;
946 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
947 DBusConnection *connection;
948 DBusMessage *dmessage;
949 DBusMessage *reply;
950 DBusMessageIter iter;
951 DBusError derror;
952 unsigned int dtype;
953 int timeout = -1;
954 int i = 5;
955 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
957 /* Check parameters. */
958 bus = args[0];
959 service = args[1];
960 path = args[2];
961 interface = args[3];
962 method = args[4];
964 CHECK_SYMBOL (bus);
965 CHECK_STRING (service);
966 CHECK_STRING (path);
967 CHECK_STRING (interface);
968 CHECK_STRING (method);
969 GCPRO5 (bus, service, path, interface, method);
971 XD_DEBUG_MESSAGE ("%s %s %s %s",
972 SDATA (service),
973 SDATA (path),
974 SDATA (interface),
975 SDATA (method));
977 /* Open a connection to the bus. */
978 connection = xd_initialize (bus);
980 /* Create the message. */
981 dmessage = dbus_message_new_method_call (SDATA (service),
982 SDATA (path),
983 SDATA (interface),
984 SDATA (method));
985 UNGCPRO;
986 if (dmessage == NULL)
987 XD_SIGNAL1 (build_string ("Unable to create a new message"));
989 /* Check for timeout parameter. */
990 if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
992 CHECK_NATNUM (args[i+1]);
993 timeout = XUINT (args[i+1]);
994 i = i+2;
997 /* Initialize parameter list of message. */
998 dbus_message_iter_init_append (dmessage, &iter);
1000 /* Append parameters to the message. */
1001 for (; i < nargs; ++i)
1003 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1004 if (XD_DBUS_TYPE_P (args[i]))
1006 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1007 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1008 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-4,
1009 SDATA (format2 ("%s", args[i], Qnil)),
1010 SDATA (format2 ("%s", args[i+1], Qnil)));
1011 ++i;
1013 else
1015 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1016 XD_DEBUG_MESSAGE ("Parameter%d %s", i-4,
1017 SDATA (format2 ("%s", args[i], Qnil)));
1020 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1021 indication that there is no parent type. */
1022 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1024 xd_append_arg (dtype, args[i], &iter);
1027 /* Send the message. */
1028 dbus_error_init (&derror);
1029 reply = dbus_connection_send_with_reply_and_block (connection,
1030 dmessage,
1031 timeout,
1032 &derror);
1034 if (dbus_error_is_set (&derror))
1035 XD_ERROR (derror);
1037 if (reply == NULL)
1038 XD_SIGNAL1 (build_string ("No reply"));
1040 XD_DEBUG_MESSAGE ("Message sent");
1042 /* Collect the results. */
1043 result = Qnil;
1044 GCPRO1 (result);
1046 if (dbus_message_iter_init (reply, &iter))
1048 /* Loop over the parameters of the D-Bus reply message. Construct a
1049 Lisp list, which is returned by `dbus-call-method'. */
1050 while ((dtype = dbus_message_iter_get_arg_type (&iter))
1051 != DBUS_TYPE_INVALID)
1053 result = Fcons (xd_retrieve_arg (dtype, &iter), result);
1054 dbus_message_iter_next (&iter);
1057 else
1059 /* No arguments: just return nil. */
1062 /* Cleanup. */
1063 dbus_error_free (&derror);
1064 dbus_message_unref (dmessage);
1065 dbus_message_unref (reply);
1067 /* Return the result. If there is only one single Lisp object,
1068 return it as-it-is, otherwise return the reversed list. */
1069 if (XUINT (Flength (result)) == 1)
1070 RETURN_UNGCPRO (CAR_SAFE (result));
1071 else
1072 RETURN_UNGCPRO (Fnreverse (result));
1075 DEFUN ("dbus-call-method-asynchronously", Fdbus_call_method_asynchronously,
1076 Sdbus_call_method_asynchronously, 6, MANY, 0,
1077 doc: /* Call METHOD on the D-Bus BUS asynchronously.
1079 BUS is either the symbol `:system' or the symbol `:session'.
1081 SERVICE is the D-Bus service name to be used. PATH is the D-Bus
1082 object path SERVICE is registered at. INTERFACE is an interface
1083 offered by SERVICE. It must provide METHOD.
1085 HANDLER is a Lisp function, which is called when the corresponding
1086 return message has arrived. If HANDLER is nil, no return message will
1087 be expected.
1089 If the parameter `:timeout' is given, the following integer TIMEOUT
1090 specifies the maximum number of milliseconds the method call must
1091 return. The default value is 25,000. If the method call doesn't
1092 return in time, a D-Bus error is raised.
1094 All other arguments ARGS are passed to METHOD as arguments. They are
1095 converted into D-Bus types via the following rules:
1097 t and nil => DBUS_TYPE_BOOLEAN
1098 number => DBUS_TYPE_UINT32
1099 integer => DBUS_TYPE_INT32
1100 float => DBUS_TYPE_DOUBLE
1101 string => DBUS_TYPE_STRING
1102 list => DBUS_TYPE_ARRAY
1104 All arguments can be preceded by a type symbol. For details about
1105 type symbols, see Info node `(dbus)Type Conversion'.
1107 Unless HANDLER is nil, the function returns a key into the hash table
1108 `dbus-registered-objects-table'. The corresponding entry in the hash
1109 table is removed, when the return message has been arrived, and
1110 HANDLER is called.
1112 Example:
1114 \(dbus-call-method-asynchronously
1115 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer"
1116 "org.freedesktop.Hal.Device" "GetPropertyString" 'message
1117 "system.kernel.machine")
1119 => (:system 2)
1121 -| i686
1123 usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLER &optional :timeout TIMEOUT &rest ARGS) */)
1124 (nargs, args)
1125 int nargs;
1126 register Lisp_Object *args;
1128 Lisp_Object bus, service, path, interface, method, handler;
1129 Lisp_Object result;
1130 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
1131 DBusConnection *connection;
1132 DBusMessage *dmessage;
1133 DBusMessageIter iter;
1134 unsigned int dtype;
1135 int timeout = -1;
1136 int i = 6;
1137 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1139 /* Check parameters. */
1140 bus = args[0];
1141 service = args[1];
1142 path = args[2];
1143 interface = args[3];
1144 method = args[4];
1145 handler = args[5];
1147 CHECK_SYMBOL (bus);
1148 CHECK_STRING (service);
1149 CHECK_STRING (path);
1150 CHECK_STRING (interface);
1151 CHECK_STRING (method);
1152 if (!NILP (handler) && !FUNCTIONP (handler))
1153 wrong_type_argument (intern ("functionp"), handler);
1154 GCPRO6 (bus, service, path, interface, method, handler);
1156 XD_DEBUG_MESSAGE ("%s %s %s %s",
1157 SDATA (service),
1158 SDATA (path),
1159 SDATA (interface),
1160 SDATA (method));
1162 /* Open a connection to the bus. */
1163 connection = xd_initialize (bus);
1165 /* Create the message. */
1166 dmessage = dbus_message_new_method_call (SDATA (service),
1167 SDATA (path),
1168 SDATA (interface),
1169 SDATA (method));
1170 if (dmessage == NULL)
1171 XD_SIGNAL1 (build_string ("Unable to create a new message"));
1173 /* Check for timeout parameter. */
1174 if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
1176 CHECK_NATNUM (args[i+1]);
1177 timeout = XUINT (args[i+1]);
1178 i = i+2;
1181 /* Initialize parameter list of message. */
1182 dbus_message_iter_init_append (dmessage, &iter);
1184 /* Append parameters to the message. */
1185 for (; i < nargs; ++i)
1187 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1188 if (XD_DBUS_TYPE_P (args[i]))
1190 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1191 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1192 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-4,
1193 SDATA (format2 ("%s", args[i], Qnil)),
1194 SDATA (format2 ("%s", args[i+1], Qnil)));
1195 ++i;
1197 else
1199 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1200 XD_DEBUG_MESSAGE ("Parameter%d %s", i-4,
1201 SDATA (format2 ("%s", args[i], Qnil)));
1204 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1205 indication that there is no parent type. */
1206 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1208 xd_append_arg (dtype, args[i], &iter);
1211 if (!NILP (handler))
1213 /* Send the message. The message is just added to the outgoing
1214 message queue. */
1215 if (!dbus_connection_send_with_reply (connection, dmessage,
1216 NULL, timeout))
1217 XD_SIGNAL1 (build_string ("Cannot send message"));
1219 /* The result is the key in Vdbus_registered_objects_table. */
1220 result = (list2 (bus, make_number (dbus_message_get_serial (dmessage))));
1222 /* Create a hash table entry. */
1223 Fputhash (result, handler, Vdbus_registered_objects_table);
1225 else
1227 /* Send the message. The message is just added to the outgoing
1228 message queue. */
1229 if (!dbus_connection_send (connection, dmessage, NULL))
1230 XD_SIGNAL1 (build_string ("Cannot send message"));
1232 result = Qnil;
1235 /* Flush connection to ensure the message is handled. */
1236 dbus_connection_flush (connection);
1238 XD_DEBUG_MESSAGE ("Message sent");
1240 /* Cleanup. */
1241 dbus_message_unref (dmessage);
1243 /* Return the result. */
1244 RETURN_UNGCPRO (result);
1247 DEFUN ("dbus-method-return-internal", Fdbus_method_return_internal,
1248 Sdbus_method_return_internal,
1249 3, MANY, 0,
1250 doc: /* Return for message SERIAL on the D-Bus BUS.
1251 This is an internal function, it shall not be used outside dbus.el.
1253 usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */)
1254 (nargs, args)
1255 int nargs;
1256 register Lisp_Object *args;
1258 Lisp_Object bus, serial, service;
1259 struct gcpro gcpro1, gcpro2, gcpro3;
1260 DBusConnection *connection;
1261 DBusMessage *dmessage;
1262 DBusMessageIter iter;
1263 unsigned int dtype;
1264 int i;
1265 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1267 /* Check parameters. */
1268 bus = args[0];
1269 serial = args[1];
1270 service = args[2];
1272 CHECK_SYMBOL (bus);
1273 CHECK_NUMBER (serial);
1274 CHECK_STRING (service);
1275 GCPRO3 (bus, serial, service);
1277 XD_DEBUG_MESSAGE ("%lu %s ", (unsigned long) XUINT (serial), SDATA (service));
1279 /* Open a connection to the bus. */
1280 connection = xd_initialize (bus);
1282 /* Create the message. */
1283 dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
1284 if ((dmessage == NULL)
1285 || (!dbus_message_set_reply_serial (dmessage, XUINT (serial)))
1286 || (!dbus_message_set_destination (dmessage, SDATA (service))))
1288 UNGCPRO;
1289 XD_SIGNAL1 (build_string ("Unable to create a return message"));
1292 UNGCPRO;
1294 /* Initialize parameter list of message. */
1295 dbus_message_iter_init_append (dmessage, &iter);
1297 /* Append parameters to the message. */
1298 for (i = 3; i < nargs; ++i)
1300 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1301 if (XD_DBUS_TYPE_P (args[i]))
1303 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1304 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1305 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-2,
1306 SDATA (format2 ("%s", args[i], Qnil)),
1307 SDATA (format2 ("%s", args[i+1], Qnil)));
1308 ++i;
1310 else
1312 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1313 XD_DEBUG_MESSAGE ("Parameter%d %s", i-2,
1314 SDATA (format2 ("%s", args[i], Qnil)));
1317 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1318 indication that there is no parent type. */
1319 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1321 xd_append_arg (dtype, args[i], &iter);
1324 /* Send the message. The message is just added to the outgoing
1325 message queue. */
1326 if (!dbus_connection_send (connection, dmessage, NULL))
1327 XD_SIGNAL1 (build_string ("Cannot send message"));
1329 /* Flush connection to ensure the message is handled. */
1330 dbus_connection_flush (connection);
1332 XD_DEBUG_MESSAGE ("Message sent");
1334 /* Cleanup. */
1335 dbus_message_unref (dmessage);
1337 /* Return. */
1338 return Qt;
1341 DEFUN ("dbus-method-error-internal", Fdbus_method_error_internal,
1342 Sdbus_method_error_internal,
1343 3, MANY, 0,
1344 doc: /* Return error message for message SERIAL on the D-Bus BUS.
1345 This is an internal function, it shall not be used outside dbus.el.
1347 usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */)
1348 (nargs, args)
1349 int nargs;
1350 register Lisp_Object *args;
1352 Lisp_Object bus, serial, service;
1353 struct gcpro gcpro1, gcpro2, gcpro3;
1354 DBusConnection *connection;
1355 DBusMessage *dmessage;
1356 DBusMessageIter iter;
1357 unsigned int dtype;
1358 int i;
1359 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1361 /* Check parameters. */
1362 bus = args[0];
1363 serial = args[1];
1364 service = args[2];
1366 CHECK_SYMBOL (bus);
1367 CHECK_NUMBER (serial);
1368 CHECK_STRING (service);
1369 GCPRO3 (bus, serial, service);
1371 XD_DEBUG_MESSAGE ("%lu %s ", (unsigned long) XUINT (serial), SDATA (service));
1373 /* Open a connection to the bus. */
1374 connection = xd_initialize (bus);
1376 /* Create the message. */
1377 dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
1378 if ((dmessage == NULL)
1379 || (!dbus_message_set_error_name (dmessage, DBUS_ERROR_FAILED))
1380 || (!dbus_message_set_reply_serial (dmessage, XUINT (serial)))
1381 || (!dbus_message_set_destination (dmessage, SDATA (service))))
1383 UNGCPRO;
1384 XD_SIGNAL1 (build_string ("Unable to create a error message"));
1387 UNGCPRO;
1389 /* Initialize parameter list of message. */
1390 dbus_message_iter_init_append (dmessage, &iter);
1392 /* Append parameters to the message. */
1393 for (i = 3; i < nargs; ++i)
1395 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1396 if (XD_DBUS_TYPE_P (args[i]))
1398 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1399 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1400 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-2,
1401 SDATA (format2 ("%s", args[i], Qnil)),
1402 SDATA (format2 ("%s", args[i+1], Qnil)));
1403 ++i;
1405 else
1407 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1408 XD_DEBUG_MESSAGE ("Parameter%d %s", i-2,
1409 SDATA (format2 ("%s", args[i], Qnil)));
1412 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1413 indication that there is no parent type. */
1414 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1416 xd_append_arg (dtype, args[i], &iter);
1419 /* Send the message. The message is just added to the outgoing
1420 message queue. */
1421 if (!dbus_connection_send (connection, dmessage, NULL))
1422 XD_SIGNAL1 (build_string ("Cannot send message"));
1424 /* Flush connection to ensure the message is handled. */
1425 dbus_connection_flush (connection);
1427 XD_DEBUG_MESSAGE ("Message sent");
1429 /* Cleanup. */
1430 dbus_message_unref (dmessage);
1432 /* Return. */
1433 return Qt;
1436 DEFUN ("dbus-send-signal", Fdbus_send_signal, Sdbus_send_signal, 5, MANY, 0,
1437 doc: /* Send signal SIGNAL on the D-Bus BUS.
1439 BUS is either the symbol `:system' or the symbol `:session'.
1441 SERVICE is the D-Bus service name SIGNAL is sent from. PATH is the
1442 D-Bus object path SERVICE is registered at. INTERFACE is an interface
1443 offered by SERVICE. It must provide signal SIGNAL.
1445 All other arguments ARGS are passed to SIGNAL as arguments. They are
1446 converted into D-Bus types via the following rules:
1448 t and nil => DBUS_TYPE_BOOLEAN
1449 number => DBUS_TYPE_UINT32
1450 integer => DBUS_TYPE_INT32
1451 float => DBUS_TYPE_DOUBLE
1452 string => DBUS_TYPE_STRING
1453 list => DBUS_TYPE_ARRAY
1455 All arguments can be preceded by a type symbol. For details about
1456 type symbols, see Info node `(dbus)Type Conversion'.
1458 Example:
1460 \(dbus-send-signal
1461 :session "org.gnu.Emacs" "/org/gnu/Emacs"
1462 "org.gnu.Emacs.FileManager" "FileModified" "/home/albinus/.emacs")
1464 usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
1465 (nargs, args)
1466 int nargs;
1467 register Lisp_Object *args;
1469 Lisp_Object bus, service, path, interface, signal;
1470 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
1471 DBusConnection *connection;
1472 DBusMessage *dmessage;
1473 DBusMessageIter iter;
1474 unsigned int dtype;
1475 int i;
1476 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1478 /* Check parameters. */
1479 bus = args[0];
1480 service = args[1];
1481 path = args[2];
1482 interface = args[3];
1483 signal = args[4];
1485 CHECK_SYMBOL (bus);
1486 CHECK_STRING (service);
1487 CHECK_STRING (path);
1488 CHECK_STRING (interface);
1489 CHECK_STRING (signal);
1490 GCPRO5 (bus, service, path, interface, signal);
1492 XD_DEBUG_MESSAGE ("%s %s %s %s",
1493 SDATA (service),
1494 SDATA (path),
1495 SDATA (interface),
1496 SDATA (signal));
1498 /* Open a connection to the bus. */
1499 connection = xd_initialize (bus);
1501 /* Create the message. */
1502 dmessage = dbus_message_new_signal (SDATA (path),
1503 SDATA (interface),
1504 SDATA (signal));
1505 UNGCPRO;
1506 if (dmessage == NULL)
1507 XD_SIGNAL1 (build_string ("Unable to create a new message"));
1509 /* Initialize parameter list of message. */
1510 dbus_message_iter_init_append (dmessage, &iter);
1512 /* Append parameters to the message. */
1513 for (i = 5; i < nargs; ++i)
1515 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1516 if (XD_DBUS_TYPE_P (args[i]))
1518 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1519 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1520 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-4,
1521 SDATA (format2 ("%s", args[i], Qnil)),
1522 SDATA (format2 ("%s", args[i+1], Qnil)));
1523 ++i;
1525 else
1527 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1528 XD_DEBUG_MESSAGE ("Parameter%d %s", i-4,
1529 SDATA (format2 ("%s", args[i], Qnil)));
1532 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1533 indication that there is no parent type. */
1534 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1536 xd_append_arg (dtype, args[i], &iter);
1539 /* Send the message. The message is just added to the outgoing
1540 message queue. */
1541 if (!dbus_connection_send (connection, dmessage, NULL))
1542 XD_SIGNAL1 (build_string ("Cannot send message"));
1544 /* Flush connection to ensure the message is handled. */
1545 dbus_connection_flush (connection);
1547 XD_DEBUG_MESSAGE ("Signal sent");
1549 /* Cleanup. */
1550 dbus_message_unref (dmessage);
1552 /* Return. */
1553 return Qt;
1556 /* Check, whether there is pending input in the message queue of the
1557 D-Bus BUS. BUS is a Lisp symbol, either :system or :session. */
1559 xd_get_dispatch_status (bus)
1560 Lisp_Object bus;
1562 DBusConnection *connection;
1564 /* Open a connection to the bus. */
1565 connection = xd_initialize (bus);
1567 /* Non blocking read of the next available message. */
1568 dbus_connection_read_write (connection, 0);
1570 /* Return. */
1571 return
1572 (dbus_connection_get_dispatch_status (connection)
1573 == DBUS_DISPATCH_DATA_REMAINS)
1574 ? TRUE : FALSE;
1577 /* Check for queued incoming messages from the system and session buses. */
1579 xd_pending_messages ()
1582 /* Vdbus_registered_objects_table will be initialized as hash table
1583 in dbus.el. When this package isn't loaded yet, it doesn't make
1584 sense to handle D-Bus messages. */
1585 return (HASH_TABLE_P (Vdbus_registered_objects_table)
1586 ? (xd_get_dispatch_status (QCdbus_system_bus)
1587 || ((getenv ("DBUS_SESSION_BUS_ADDRESS") != NULL)
1588 ? xd_get_dispatch_status (QCdbus_session_bus)
1589 : FALSE))
1590 : FALSE);
1593 /* Read queued incoming message of the D-Bus BUS. BUS is a Lisp
1594 symbol, either :system or :session. */
1595 static Lisp_Object
1596 xd_read_message (bus)
1597 Lisp_Object bus;
1599 Lisp_Object args, key, value;
1600 struct gcpro gcpro1;
1601 struct input_event event;
1602 DBusConnection *connection;
1603 DBusMessage *dmessage;
1604 DBusMessageIter iter;
1605 unsigned int dtype;
1606 int mtype, serial;
1607 const char *uname, *path, *interface, *member;
1609 /* Open a connection to the bus. */
1610 connection = xd_initialize (bus);
1612 /* Non blocking read of the next available message. */
1613 dbus_connection_read_write (connection, 0);
1614 dmessage = dbus_connection_pop_message (connection);
1616 /* Return if there is no queued message. */
1617 if (dmessage == NULL)
1618 return Qnil;
1620 /* Collect the parameters. */
1621 args = Qnil;
1622 GCPRO1 (args);
1624 /* Loop over the resulting parameters. Construct a list. */
1625 if (dbus_message_iter_init (dmessage, &iter))
1627 while ((dtype = dbus_message_iter_get_arg_type (&iter))
1628 != DBUS_TYPE_INVALID)
1630 args = Fcons (xd_retrieve_arg (dtype, &iter), args);
1631 dbus_message_iter_next (&iter);
1633 /* The arguments are stored in reverse order. Reorder them. */
1634 args = Fnreverse (args);
1637 /* Read message type, message serial, unique name, object path,
1638 interface and member from the message. */
1639 mtype = dbus_message_get_type (dmessage);
1640 serial =
1641 ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1642 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1643 ? dbus_message_get_reply_serial (dmessage)
1644 : dbus_message_get_serial (dmessage);
1645 uname = dbus_message_get_sender (dmessage);
1646 path = dbus_message_get_path (dmessage);
1647 interface = dbus_message_get_interface (dmessage);
1648 member = dbus_message_get_member (dmessage);
1650 XD_DEBUG_MESSAGE ("Event received: %s %d %s %s %s %s %s",
1651 (mtype == DBUS_MESSAGE_TYPE_INVALID)
1652 ? "DBUS_MESSAGE_TYPE_INVALID"
1653 : (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1654 ? "DBUS_MESSAGE_TYPE_METHOD_CALL"
1655 : (mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1656 ? "DBUS_MESSAGE_TYPE_METHOD_RETURN"
1657 : (mtype == DBUS_MESSAGE_TYPE_ERROR)
1658 ? "DBUS_MESSAGE_TYPE_ERROR"
1659 : "DBUS_MESSAGE_TYPE_SIGNAL",
1660 serial, uname, path, interface, member,
1661 SDATA (format2 ("%s", args, Qnil)));
1663 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1664 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1666 /* Search for a registered function of the message. */
1667 key = list2 (bus, make_number (serial));
1668 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1670 /* There shall be exactly one entry. Construct an event. */
1671 if (NILP (value))
1672 goto cleanup;
1674 /* Remove the entry. */
1675 Fremhash (key, Vdbus_registered_objects_table);
1677 /* Construct an event. */
1678 EVENT_INIT (event);
1679 event.kind = DBUS_EVENT;
1680 event.frame_or_window = Qnil;
1681 event.arg = Fcons (value, args);
1684 else /* (mtype != DBUS_MESSAGE_TYPE_METHOD_RETURN) */
1686 /* Vdbus_registered_objects_table requires non-nil interface and
1687 member. */
1688 if ((interface == NULL) || (member == NULL))
1689 goto cleanup;
1691 /* Search for a registered function of the message. */
1692 key = list3 (bus, build_string (interface), build_string (member));
1693 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1695 /* Loop over the registered functions. Construct an event. */
1696 while (!NILP (value))
1698 key = CAR_SAFE (value);
1699 /* key has the structure (UNAME SERVICE PATH HANDLER). */
1700 if (((uname == NULL)
1701 || (NILP (CAR_SAFE (key)))
1702 || (strcmp (uname, SDATA (CAR_SAFE (key))) == 0))
1703 && ((path == NULL)
1704 || (NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (key)))))
1705 || (strcmp (path,
1706 SDATA (CAR_SAFE (CDR_SAFE (CDR_SAFE (key)))))
1707 == 0))
1708 && (!NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))))))
1710 EVENT_INIT (event);
1711 event.kind = DBUS_EVENT;
1712 event.frame_or_window = Qnil;
1713 event.arg = Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))),
1714 args);
1715 break;
1717 value = CDR_SAFE (value);
1720 if (NILP (value))
1721 goto cleanup;
1724 /* Add type, serial, uname, path, interface and member to the event. */
1725 event.arg = Fcons ((member == NULL ? Qnil : build_string (member)),
1726 event.arg);
1727 event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)),
1728 event.arg);
1729 event.arg = Fcons ((path == NULL ? Qnil : build_string (path)),
1730 event.arg);
1731 event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)),
1732 event.arg);
1733 event.arg = Fcons (make_number (serial), event.arg);
1734 event.arg = Fcons (make_number (mtype), event.arg);
1736 /* Add the bus symbol to the event. */
1737 event.arg = Fcons (bus, event.arg);
1739 /* Store it into the input event queue. */
1740 kbd_buffer_store_event (&event);
1742 XD_DEBUG_MESSAGE ("Event stored: %s",
1743 SDATA (format2 ("%s", event.arg, Qnil)));
1745 /* Cleanup. */
1746 cleanup:
1747 dbus_message_unref (dmessage);
1749 RETURN_UNGCPRO (Qnil);
1752 /* Read queued incoming messages from the system and session buses. */
1753 void
1754 xd_read_queued_messages ()
1757 /* Vdbus_registered_objects_table will be initialized as hash table
1758 in dbus.el. When this package isn't loaded yet, it doesn't make
1759 sense to handle D-Bus messages. Furthermore, we ignore all Lisp
1760 errors during the call. */
1761 if (HASH_TABLE_P (Vdbus_registered_objects_table))
1763 xd_in_read_queued_messages = 1;
1764 internal_catch (Qdbus_error, xd_read_message, QCdbus_system_bus);
1765 internal_catch (Qdbus_error, xd_read_message, QCdbus_session_bus);
1766 xd_in_read_queued_messages = 0;
1770 DEFUN ("dbus-register-signal", Fdbus_register_signal, Sdbus_register_signal,
1771 6, MANY, 0,
1772 doc: /* Register for signal SIGNAL on the D-Bus BUS.
1774 BUS is either the symbol `:system' or the symbol `:session'.
1776 SERVICE is the D-Bus service name used by the sending D-Bus object.
1777 It can be either a known name or the unique name of the D-Bus object
1778 sending the signal. When SERVICE is nil, related signals from all
1779 D-Bus objects shall be accepted.
1781 PATH is the D-Bus object path SERVICE is registered. It can also be
1782 nil if the path name of incoming signals shall not be checked.
1784 INTERFACE is an interface offered by SERVICE. It must provide SIGNAL.
1785 HANDLER is a Lisp function to be called when the signal is received.
1786 It must accept as arguments the values SIGNAL is sending.
1788 All other arguments ARGS, if specified, must be strings. They stand
1789 for the respective arguments of the signal in their order, and are
1790 used for filtering as well. A nil argument might be used to preserve
1791 the order.
1793 INTERFACE, SIGNAL and HANDLER must not be nil. Example:
1795 \(defun my-signal-handler (device)
1796 (message "Device %s added" device))
1798 \(dbus-register-signal
1799 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/Manager"
1800 "org.freedesktop.Hal.Manager" "DeviceAdded" 'my-signal-handler)
1802 => ((:system "org.freedesktop.Hal.Manager" "DeviceAdded")
1803 ("org.freedesktop.Hal" "/org/freedesktop/Hal/Manager" my-signal-handler))
1805 `dbus-register-signal' returns an object, which can be used in
1806 `dbus-unregister-object' for removing the registration.
1808 usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARGS) */)
1809 (nargs, args)
1810 int nargs;
1811 register Lisp_Object *args;
1813 Lisp_Object bus, service, path, interface, signal, handler;
1814 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
1815 Lisp_Object uname, key, key1, value;
1816 DBusConnection *connection;
1817 int i;
1818 char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
1819 char x[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
1820 DBusError derror;
1822 /* Check parameters. */
1823 bus = args[0];
1824 service = args[1];
1825 path = args[2];
1826 interface = args[3];
1827 signal = args[4];
1828 handler = args[5];
1830 CHECK_SYMBOL (bus);
1831 if (!NILP (service)) CHECK_STRING (service);
1832 if (!NILP (path)) CHECK_STRING (path);
1833 CHECK_STRING (interface);
1834 CHECK_STRING (signal);
1835 if (!FUNCTIONP (handler))
1836 wrong_type_argument (intern ("functionp"), handler);
1837 GCPRO6 (bus, service, path, interface, signal, handler);
1839 /* Retrieve unique name of service. If service is a known name, we
1840 will register for the corresponding unique name, if any. Signals
1841 are sent always with the unique name as sender. Note: the unique
1842 name of "org.freedesktop.DBus" is that string itself. */
1843 if ((STRINGP (service))
1844 && (SBYTES (service) > 0)
1845 && (strcmp (SDATA (service), DBUS_SERVICE_DBUS) != 0)
1846 && (strncmp (SDATA (service), ":", 1) != 0))
1848 uname = call2 (intern ("dbus-get-name-owner"), bus, service);
1849 /* When there is no unique name, we mark it with an empty
1850 string. */
1851 if (NILP (uname))
1852 uname = empty_unibyte_string;
1854 else
1855 uname = service;
1857 /* Create a matching rule if the unique name exists (when no
1858 wildcard). */
1859 if (NILP (uname) || (SBYTES (uname) > 0))
1861 /* Open a connection to the bus. */
1862 connection = xd_initialize (bus);
1864 /* Create a rule to receive related signals. */
1865 sprintf (rule,
1866 "type='signal',interface='%s',member='%s'",
1867 SDATA (interface),
1868 SDATA (signal));
1870 /* Add unique name and path to the rule if they are non-nil. */
1871 if (!NILP (uname))
1873 sprintf (x, ",sender='%s'", SDATA (uname));
1874 strcat (rule, x);
1877 if (!NILP (path))
1879 sprintf (x, ",path='%s'", SDATA (path));
1880 strcat (rule, x);
1883 /* Add arguments to the rule if they are non-nil. */
1884 for (i = 6; i < nargs; ++i)
1885 if (!NILP (args[i]))
1887 CHECK_STRING (args[i]);
1888 sprintf (x, ",arg%d='%s'", i-6, SDATA (args[i]));
1889 strcat (rule, x);
1892 /* Add the rule to the bus. */
1893 dbus_error_init (&derror);
1894 dbus_bus_add_match (connection, rule, &derror);
1895 if (dbus_error_is_set (&derror))
1897 UNGCPRO;
1898 XD_ERROR (derror);
1901 /* Cleanup. */
1902 dbus_error_free (&derror);
1904 XD_DEBUG_MESSAGE ("Matching rule \"%s\" created", rule);
1907 /* Create a hash table entry. */
1908 key = list3 (bus, interface, signal);
1909 key1 = list4 (uname, service, path, handler);
1910 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1912 if (NILP (Fmember (key1, value)))
1913 Fputhash (key, Fcons (key1, value), Vdbus_registered_objects_table);
1915 /* Return object. */
1916 RETURN_UNGCPRO (list2 (key, list3 (service, path, handler)));
1919 DEFUN ("dbus-register-method", Fdbus_register_method, Sdbus_register_method,
1920 6, 6, 0,
1921 doc: /* Register for method METHOD on the D-Bus BUS.
1923 BUS is either the symbol `:system' or the symbol `:session'.
1925 SERVICE is the D-Bus service name of the D-Bus object METHOD is
1926 registered for. It must be a known name.
1928 PATH is the D-Bus object path SERVICE is registered. INTERFACE is the
1929 interface offered by SERVICE. It must provide METHOD. HANDLER is a
1930 Lisp function to be called when a method call is received. It must
1931 accept the input arguments of METHOD. The return value of HANDLER is
1932 used for composing the returning D-Bus message. */)
1933 (bus, service, path, interface, method, handler)
1934 Lisp_Object bus, service, path, interface, method, handler;
1936 Lisp_Object key, key1, value;
1937 DBusConnection *connection;
1938 int result;
1939 DBusError derror;
1941 /* Check parameters. */
1942 CHECK_SYMBOL (bus);
1943 CHECK_STRING (service);
1944 CHECK_STRING (path);
1945 CHECK_STRING (interface);
1946 CHECK_STRING (method);
1947 if (!FUNCTIONP (handler))
1948 wrong_type_argument (intern ("functionp"), handler);
1949 /* TODO: We must check for a valid service name, otherwise there is
1950 a segmentation fault. */
1952 /* Open a connection to the bus. */
1953 connection = xd_initialize (bus);
1955 /* Request the known name from the bus. We can ignore the result,
1956 it is set to -1 if there is an error - kind of redundancy. */
1957 dbus_error_init (&derror);
1958 result = dbus_bus_request_name (connection, SDATA (service), 0, &derror);
1959 if (dbus_error_is_set (&derror))
1960 XD_ERROR (derror);
1962 /* Create a hash table entry. We use nil for the unique name,
1963 because the method might be called from anybody. */
1964 key = list3 (bus, interface, method);
1965 key1 = list4 (Qnil, service, path, handler);
1966 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1968 if (NILP (Fmember (key1, value)))
1969 Fputhash (key, Fcons (key1, value), Vdbus_registered_objects_table);
1971 /* Cleanup. */
1972 dbus_error_free (&derror);
1974 /* Return object. */
1975 return list2 (key, list3 (service, path, handler));
1979 void
1980 syms_of_dbusbind ()
1983 Qdbus_init_bus = intern_c_string ("dbus-init-bus");
1984 staticpro (&Qdbus_init_bus);
1985 defsubr (&Sdbus_init_bus);
1987 Qdbus_get_unique_name = intern_c_string ("dbus-get-unique-name");
1988 staticpro (&Qdbus_get_unique_name);
1989 defsubr (&Sdbus_get_unique_name);
1991 Qdbus_call_method = intern_c_string ("dbus-call-method");
1992 staticpro (&Qdbus_call_method);
1993 defsubr (&Sdbus_call_method);
1995 Qdbus_call_method_asynchronously = intern_c_string ("dbus-call-method-asynchronously");
1996 staticpro (&Qdbus_call_method_asynchronously);
1997 defsubr (&Sdbus_call_method_asynchronously);
1999 Qdbus_method_return_internal = intern_c_string ("dbus-method-return-internal");
2000 staticpro (&Qdbus_method_return_internal);
2001 defsubr (&Sdbus_method_return_internal);
2003 Qdbus_method_error_internal = intern_c_string ("dbus-method-error-internal");
2004 staticpro (&Qdbus_method_error_internal);
2005 defsubr (&Sdbus_method_error_internal);
2007 Qdbus_send_signal = intern_c_string ("dbus-send-signal");
2008 staticpro (&Qdbus_send_signal);
2009 defsubr (&Sdbus_send_signal);
2011 Qdbus_register_signal = intern_c_string ("dbus-register-signal");
2012 staticpro (&Qdbus_register_signal);
2013 defsubr (&Sdbus_register_signal);
2015 Qdbus_register_method = intern_c_string ("dbus-register-method");
2016 staticpro (&Qdbus_register_method);
2017 defsubr (&Sdbus_register_method);
2019 Qdbus_error = intern_c_string ("dbus-error");
2020 staticpro (&Qdbus_error);
2021 Fput (Qdbus_error, Qerror_conditions,
2022 list2 (Qdbus_error, Qerror));
2023 Fput (Qdbus_error, Qerror_message,
2024 make_pure_c_string ("D-Bus error"));
2026 QCdbus_system_bus = intern_c_string (":system");
2027 staticpro (&QCdbus_system_bus);
2029 QCdbus_session_bus = intern_c_string (":session");
2030 staticpro (&QCdbus_session_bus);
2032 QCdbus_timeout = intern_c_string (":timeout");
2033 staticpro (&QCdbus_timeout);
2035 QCdbus_type_byte = intern_c_string (":byte");
2036 staticpro (&QCdbus_type_byte);
2038 QCdbus_type_boolean = intern_c_string (":boolean");
2039 staticpro (&QCdbus_type_boolean);
2041 QCdbus_type_int16 = intern_c_string (":int16");
2042 staticpro (&QCdbus_type_int16);
2044 QCdbus_type_uint16 = intern_c_string (":uint16");
2045 staticpro (&QCdbus_type_uint16);
2047 QCdbus_type_int32 = intern_c_string (":int32");
2048 staticpro (&QCdbus_type_int32);
2050 QCdbus_type_uint32 = intern_c_string (":uint32");
2051 staticpro (&QCdbus_type_uint32);
2053 QCdbus_type_int64 = intern_c_string (":int64");
2054 staticpro (&QCdbus_type_int64);
2056 QCdbus_type_uint64 = intern_c_string (":uint64");
2057 staticpro (&QCdbus_type_uint64);
2059 QCdbus_type_double = intern_c_string (":double");
2060 staticpro (&QCdbus_type_double);
2062 QCdbus_type_string = intern_c_string (":string");
2063 staticpro (&QCdbus_type_string);
2065 QCdbus_type_object_path = intern_c_string (":object-path");
2066 staticpro (&QCdbus_type_object_path);
2068 QCdbus_type_signature = intern_c_string (":signature");
2069 staticpro (&QCdbus_type_signature);
2071 QCdbus_type_array = intern_c_string (":array");
2072 staticpro (&QCdbus_type_array);
2074 QCdbus_type_variant = intern_c_string (":variant");
2075 staticpro (&QCdbus_type_variant);
2077 QCdbus_type_struct = intern_c_string (":struct");
2078 staticpro (&QCdbus_type_struct);
2080 QCdbus_type_dict_entry = intern_c_string (":dict-entry");
2081 staticpro (&QCdbus_type_dict_entry);
2083 DEFVAR_LISP ("dbus-registered-objects-table",
2084 &Vdbus_registered_objects_table,
2085 doc: /* Hash table of registered functions for D-Bus.
2086 There are two different uses of the hash table: for accessing
2087 registered interfaces properties, targeted by signals or method calls,
2088 and for calling handlers in case of non-blocking method call returns.
2090 In the first case, the key in the hash table is the list (BUS
2091 INTERFACE MEMBER). BUS is either the symbol `:system' or the symbol
2092 `:session'. INTERFACE is a string which denotes a D-Bus interface,
2093 and MEMBER, also a string, is either a method, a signal or a property
2094 INTERFACE is offering. All arguments but BUS must not be nil.
2096 The value in the hash table is a list of quadruple lists
2097 \((UNAME SERVICE PATH OBJECT) (UNAME SERVICE PATH OBJECT) ...).
2098 SERVICE is the service name as registered, UNAME is the corresponding
2099 unique name. In case of registered methods and properties, UNAME is
2100 nil. PATH is the object path of the sending object. All of them can
2101 be nil, which means a wildcard then. OBJECT is either the handler to
2102 be called when a D-Bus message, which matches the key criteria,
2103 arrives (methods and signals), or a cons cell containing the value of
2104 the property.
2106 In the second case, the key in the hash table is the list (BUS SERIAL).
2107 BUS is either the symbol `:system' or the symbol `:session'. SERIAL
2108 is the serial number of the non-blocking method call, a reply is
2109 expected. Both arguments must not be nil. The value in the hash
2110 table is HANDLER, the function to be called when the D-Bus reply
2111 message arrives. */);
2112 /* We initialize Vdbus_registered_objects_table in dbus.el, because
2113 we need to define a hash table function first. */
2114 Vdbus_registered_objects_table = Qnil;
2116 DEFVAR_LISP ("dbus-debug", &Vdbus_debug,
2117 doc: /* If non-nil, debug messages of D-Bus bindings are raised. */);
2118 #ifdef DBUS_DEBUG
2119 Vdbus_debug = Qt;
2120 #else
2121 Vdbus_debug = Qnil;
2122 #endif
2124 Fprovide (intern_c_string ("dbusbind"), Qnil);
2128 #endif /* HAVE_DBUS */
2130 /* arch-tag: 0e828477-b571-4fe4-b559-5c9211bc14b8
2131 (do not change this comment) */