* lisp/avoid.el (mouse-avoidance-ignore-p): Ignore mouse when it is
[emacs.git] / src / dbusbind.c
blob683b7cb583b6889cacd446bfccf8a5c690530af1
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 <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"
32 /* Subroutines. */
33 Lisp_Object Qdbus_init_bus;
34 Lisp_Object Qdbus_close_bus;
35 Lisp_Object Qdbus_get_unique_name;
36 Lisp_Object Qdbus_call_method;
37 Lisp_Object Qdbus_call_method_asynchronously;
38 Lisp_Object Qdbus_method_return_internal;
39 Lisp_Object Qdbus_method_error_internal;
40 Lisp_Object Qdbus_send_signal;
41 Lisp_Object Qdbus_register_signal;
42 Lisp_Object Qdbus_register_method;
44 /* D-Bus error symbol. */
45 Lisp_Object Qdbus_error;
47 /* Lisp symbols of the system and session buses. */
48 Lisp_Object QCdbus_system_bus, QCdbus_session_bus;
50 /* Lisp symbol for method call timeout. */
51 Lisp_Object QCdbus_timeout;
53 /* Lisp symbols of D-Bus types. */
54 Lisp_Object QCdbus_type_byte, QCdbus_type_boolean;
55 Lisp_Object QCdbus_type_int16, QCdbus_type_uint16;
56 Lisp_Object QCdbus_type_int32, QCdbus_type_uint32;
57 Lisp_Object QCdbus_type_int64, QCdbus_type_uint64;
58 Lisp_Object QCdbus_type_double, QCdbus_type_string;
59 Lisp_Object QCdbus_type_object_path, QCdbus_type_signature;
60 Lisp_Object QCdbus_type_array, QCdbus_type_variant;
61 Lisp_Object QCdbus_type_struct, QCdbus_type_dict_entry;
63 /* Registered buses. */
64 Lisp_Object Vdbus_registered_buses;
66 /* Hash table which keeps function definitions. */
67 Lisp_Object Vdbus_registered_objects_table;
69 /* Whether to debug D-Bus. */
70 Lisp_Object Vdbus_debug;
72 /* Whether we are reading a D-Bus event. */
73 int xd_in_read_queued_messages = 0;
76 /* We use "xd_" and "XD_" as prefix for all internal symbols, because
77 we don't want to poison other namespaces with "dbus_". */
79 /* Raise a signal. If we are reading events, we cannot signal; we
80 throw to xd_read_queued_messages then. */
81 #define XD_SIGNAL1(arg) \
82 do { \
83 if (xd_in_read_queued_messages) \
84 Fthrow (Qdbus_error, Qnil); \
85 else \
86 xsignal1 (Qdbus_error, arg); \
87 } while (0)
89 #define XD_SIGNAL2(arg1, arg2) \
90 do { \
91 if (xd_in_read_queued_messages) \
92 Fthrow (Qdbus_error, Qnil); \
93 else \
94 xsignal2 (Qdbus_error, arg1, arg2); \
95 } while (0)
97 #define XD_SIGNAL3(arg1, arg2, arg3) \
98 do { \
99 if (xd_in_read_queued_messages) \
100 Fthrow (Qdbus_error, Qnil); \
101 else \
102 xsignal3 (Qdbus_error, arg1, arg2, arg3); \
103 } while (0)
105 /* Raise a Lisp error from a D-Bus ERROR. */
106 #define XD_ERROR(error) \
107 do { \
108 char s[1024]; \
109 strncpy (s, error.message, 1023); \
110 dbus_error_free (&error); \
111 /* Remove the trailing newline. */ \
112 if (strchr (s, '\n') != NULL) \
113 s[strlen (s) - 1] = '\0'; \
114 XD_SIGNAL1 (build_string (s)); \
115 } while (0)
117 /* Macros for debugging. In order to enable them, build with
118 "MYCPPFLAGS='-DDBUS_DEBUG -Wall' make". */
119 #ifdef DBUS_DEBUG
120 #define XD_DEBUG_MESSAGE(...) \
121 do { \
122 char s[1024]; \
123 snprintf (s, 1023, __VA_ARGS__); \
124 printf ("%s: %s\n", __func__, s); \
125 message ("%s: %s", __func__, s); \
126 } while (0)
127 #define XD_DEBUG_VALID_LISP_OBJECT_P(object) \
128 do { \
129 if (!valid_lisp_object_p (object)) \
131 XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__); \
132 XD_SIGNAL1 (build_string ("Assertion failure")); \
134 } while (0)
136 #else /* !DBUS_DEBUG */
137 #define XD_DEBUG_MESSAGE(...) \
138 do { \
139 if (!NILP (Vdbus_debug)) \
141 char s[1024]; \
142 snprintf (s, 1023, __VA_ARGS__); \
143 message ("%s: %s", __func__, s); \
145 } while (0)
146 #define XD_DEBUG_VALID_LISP_OBJECT_P(object)
147 #endif
149 /* Check whether TYPE is a basic DBusType. */
150 #define XD_BASIC_DBUS_TYPE(type) \
151 ((type == DBUS_TYPE_BYTE) \
152 || (type == DBUS_TYPE_BOOLEAN) \
153 || (type == DBUS_TYPE_INT16) \
154 || (type == DBUS_TYPE_UINT16) \
155 || (type == DBUS_TYPE_INT32) \
156 || (type == DBUS_TYPE_UINT32) \
157 || (type == DBUS_TYPE_INT64) \
158 || (type == DBUS_TYPE_UINT64) \
159 || (type == DBUS_TYPE_DOUBLE) \
160 || (type == DBUS_TYPE_STRING) \
161 || (type == DBUS_TYPE_OBJECT_PATH) \
162 || (type == DBUS_TYPE_SIGNATURE))
164 /* This was a macro. On Solaris 2.11 it was said to compile for
165 hours, when optimzation is enabled. So we have transferred it into
166 a function. */
167 /* Determine the DBusType of a given Lisp symbol. OBJECT must be one
168 of the predefined D-Bus type symbols. */
169 static int
170 xd_symbol_to_dbus_type (Lisp_Object object)
172 return
173 ((EQ (object, QCdbus_type_byte)) ? DBUS_TYPE_BYTE
174 : (EQ (object, QCdbus_type_boolean)) ? DBUS_TYPE_BOOLEAN
175 : (EQ (object, QCdbus_type_int16)) ? DBUS_TYPE_INT16
176 : (EQ (object, QCdbus_type_uint16)) ? DBUS_TYPE_UINT16
177 : (EQ (object, QCdbus_type_int32)) ? DBUS_TYPE_INT32
178 : (EQ (object, QCdbus_type_uint32)) ? DBUS_TYPE_UINT32
179 : (EQ (object, QCdbus_type_int64)) ? DBUS_TYPE_INT64
180 : (EQ (object, QCdbus_type_uint64)) ? DBUS_TYPE_UINT64
181 : (EQ (object, QCdbus_type_double)) ? DBUS_TYPE_DOUBLE
182 : (EQ (object, QCdbus_type_string)) ? DBUS_TYPE_STRING
183 : (EQ (object, QCdbus_type_object_path)) ? DBUS_TYPE_OBJECT_PATH
184 : (EQ (object, QCdbus_type_signature)) ? DBUS_TYPE_SIGNATURE
185 : (EQ (object, QCdbus_type_array)) ? DBUS_TYPE_ARRAY
186 : (EQ (object, QCdbus_type_variant)) ? DBUS_TYPE_VARIANT
187 : (EQ (object, QCdbus_type_struct)) ? DBUS_TYPE_STRUCT
188 : (EQ (object, QCdbus_type_dict_entry)) ? DBUS_TYPE_DICT_ENTRY
189 : DBUS_TYPE_INVALID);
192 /* Check whether a Lisp symbol is a predefined D-Bus type symbol. */
193 #define XD_DBUS_TYPE_P(object) \
194 (SYMBOLP (object) && ((xd_symbol_to_dbus_type (object) != DBUS_TYPE_INVALID)))
196 /* Determine the DBusType of a given Lisp OBJECT. It is used to
197 convert Lisp objects, being arguments of `dbus-call-method' or
198 `dbus-send-signal', into corresponding C values appended as
199 arguments to a D-Bus message. */
200 #define XD_OBJECT_TO_DBUS_TYPE(object) \
201 ((EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN \
202 : (NATNUMP (object)) ? DBUS_TYPE_UINT32 \
203 : (INTEGERP (object)) ? DBUS_TYPE_INT32 \
204 : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \
205 : (STRINGP (object)) ? DBUS_TYPE_STRING \
206 : (XD_DBUS_TYPE_P (object)) ? xd_symbol_to_dbus_type (object) \
207 : (CONSP (object)) \
208 ? ((XD_DBUS_TYPE_P (CAR_SAFE (object))) \
209 ? ((XD_BASIC_DBUS_TYPE (xd_symbol_to_dbus_type (CAR_SAFE (object)))) \
210 ? DBUS_TYPE_ARRAY \
211 : xd_symbol_to_dbus_type (CAR_SAFE (object))) \
212 : DBUS_TYPE_ARRAY) \
213 : DBUS_TYPE_INVALID)
215 /* Return a list pointer which does not have a Lisp symbol as car. */
216 #define XD_NEXT_VALUE(object) \
217 ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object)
219 /* Compute SIGNATURE of OBJECT. It must have a form that it can be
220 used in dbus_message_iter_open_container. DTYPE is the DBusType
221 the object is related to. It is passed as argument, because it
222 cannot be detected in basic type objects, when they are preceded by
223 a type symbol. PARENT_TYPE is the DBusType of a container this
224 signature is embedded, or DBUS_TYPE_INVALID. It is needed for the
225 check that DBUS_TYPE_DICT_ENTRY occurs only as array element. */
226 static void
227 xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, 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 (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter)
398 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
399 DBusMessageIter subiter;
401 if (XD_BASIC_DBUS_TYPE (dtype))
402 switch (dtype)
404 case DBUS_TYPE_BYTE:
405 CHECK_NUMBER (object);
407 unsigned char val = XUINT (object) & 0xFF;
408 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
409 if (!dbus_message_iter_append_basic (iter, dtype, &val))
410 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
411 return;
414 case DBUS_TYPE_BOOLEAN:
416 dbus_bool_t val = (NILP (object)) ? FALSE : TRUE;
417 XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
418 if (!dbus_message_iter_append_basic (iter, dtype, &val))
419 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
420 return;
423 case DBUS_TYPE_INT16:
424 CHECK_NUMBER (object);
426 dbus_int16_t val = XINT (object);
427 XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
428 if (!dbus_message_iter_append_basic (iter, dtype, &val))
429 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
430 return;
433 case DBUS_TYPE_UINT16:
434 CHECK_NUMBER (object);
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:
444 CHECK_NUMBER (object);
446 dbus_int32_t val = XINT (object);
447 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
448 if (!dbus_message_iter_append_basic (iter, dtype, &val))
449 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
450 return;
453 case DBUS_TYPE_UINT32:
454 CHECK_NUMBER (object);
456 dbus_uint32_t val = XUINT (object);
457 XD_DEBUG_MESSAGE ("%c %u", dtype, val);
458 if (!dbus_message_iter_append_basic (iter, dtype, &val))
459 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
460 return;
463 case DBUS_TYPE_INT64:
464 CHECK_NUMBER (object);
466 dbus_int64_t val = XINT (object);
467 XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
468 if (!dbus_message_iter_append_basic (iter, dtype, &val))
469 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
470 return;
473 case DBUS_TYPE_UINT64:
474 CHECK_NUMBER (object);
476 dbus_uint64_t val = XUINT (object);
477 XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val);
478 if (!dbus_message_iter_append_basic (iter, dtype, &val))
479 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
480 return;
483 case DBUS_TYPE_DOUBLE:
484 CHECK_FLOAT (object);
486 double val = XFLOAT_DATA (object);
487 XD_DEBUG_MESSAGE ("%c %f", dtype, val);
488 if (!dbus_message_iter_append_basic (iter, dtype, &val))
489 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
490 return;
493 case DBUS_TYPE_STRING:
494 case DBUS_TYPE_OBJECT_PATH:
495 case DBUS_TYPE_SIGNATURE:
496 CHECK_STRING (object);
498 /* We need to send a valid UTF-8 string. We could encode `object'
499 but by not encoding it, we guarantee it's valid utf-8, even if
500 it contains eight-bit-bytes. Of course, you can still send
501 manually-crafted junk by passing a unibyte string. */
502 char *val = SDATA (object);
503 XD_DEBUG_MESSAGE ("%c %s", dtype, val);
504 if (!dbus_message_iter_append_basic (iter, dtype, &val))
505 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
506 return;
510 else /* Compound types. */
513 /* All compound types except array have a type symbol. For
514 array, it is optional. Skip it. */
515 if (!XD_BASIC_DBUS_TYPE (XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object))))
516 object = XD_NEXT_VALUE (object);
518 /* Open new subiteration. */
519 switch (dtype)
521 case DBUS_TYPE_ARRAY:
522 /* An array has only elements of the same type. So it is
523 sufficient to check the first element's signature
524 only. */
526 if (NILP (object))
527 /* If the array is empty, DBUS_TYPE_STRING is the default
528 element type. */
529 strcpy (signature, DBUS_TYPE_STRING_AS_STRING);
531 else
532 /* If the element type is DBUS_TYPE_SIGNATURE, and this is
533 the only element, the value of this element is used as
534 the array's element signature. */
535 if ((XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object))
536 == DBUS_TYPE_SIGNATURE)
537 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object)))
538 && NILP (CDR_SAFE (XD_NEXT_VALUE (object))))
540 strcpy (signature, SDATA (CAR_SAFE (XD_NEXT_VALUE (object))));
541 object = CDR_SAFE (XD_NEXT_VALUE (object));
544 else
545 xd_signature (signature,
546 XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)),
547 dtype, CAR_SAFE (XD_NEXT_VALUE (object)));
549 XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature,
550 SDATA (format2 ("%s", object, Qnil)));
551 if (!dbus_message_iter_open_container (iter, dtype,
552 signature, &subiter))
553 XD_SIGNAL3 (build_string ("Cannot open container"),
554 make_number (dtype), build_string (signature));
555 break;
557 case DBUS_TYPE_VARIANT:
558 /* A variant has just one element. */
559 xd_signature (signature, XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)),
560 dtype, CAR_SAFE (XD_NEXT_VALUE (object)));
562 XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature,
563 SDATA (format2 ("%s", object, Qnil)));
564 if (!dbus_message_iter_open_container (iter, dtype,
565 signature, &subiter))
566 XD_SIGNAL3 (build_string ("Cannot open container"),
567 make_number (dtype), build_string (signature));
568 break;
570 case DBUS_TYPE_STRUCT:
571 case DBUS_TYPE_DICT_ENTRY:
572 /* These containers do not require a signature. */
573 XD_DEBUG_MESSAGE ("%c %s", dtype,
574 SDATA (format2 ("%s", object, Qnil)));
575 if (!dbus_message_iter_open_container (iter, dtype, NULL, &subiter))
576 XD_SIGNAL2 (build_string ("Cannot open container"),
577 make_number (dtype));
578 break;
581 /* Loop over list elements. */
582 while (!NILP (object))
584 dtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object));
585 object = XD_NEXT_VALUE (object);
587 xd_append_arg (dtype, CAR_SAFE (object), &subiter);
589 object = CDR_SAFE (object);
592 /* Close the subiteration. */
593 if (!dbus_message_iter_close_container (iter, &subiter))
594 XD_SIGNAL2 (build_string ("Cannot close container"),
595 make_number (dtype));
599 /* Retrieve C value from a DBusMessageIter structure ITER, and return
600 a converted Lisp object. The type DTYPE of the argument of the
601 D-Bus message must be a valid DBusType. Compound D-Bus types
602 result always in a Lisp list. */
603 static Lisp_Object
604 xd_retrieve_arg (unsigned int dtype, DBusMessageIter *iter)
607 switch (dtype)
609 case DBUS_TYPE_BYTE:
611 unsigned int val;
612 dbus_message_iter_get_basic (iter, &val);
613 val = val & 0xFF;
614 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
615 return make_number (val);
618 case DBUS_TYPE_BOOLEAN:
620 dbus_bool_t val;
621 dbus_message_iter_get_basic (iter, &val);
622 XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
623 return (val == FALSE) ? Qnil : Qt;
626 case DBUS_TYPE_INT16:
628 dbus_int16_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_UINT16:
636 dbus_uint16_t val;
637 dbus_message_iter_get_basic (iter, &val);
638 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
639 return make_number (val);
642 case DBUS_TYPE_INT32:
644 dbus_int32_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_UINT32:
652 dbus_uint32_t val;
653 dbus_message_iter_get_basic (iter, &val);
654 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
655 return make_fixnum_or_float (val);
658 case DBUS_TYPE_INT64:
660 dbus_int64_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_UINT64:
668 dbus_uint64_t val;
669 dbus_message_iter_get_basic (iter, &val);
670 XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
671 return make_fixnum_or_float (val);
674 case DBUS_TYPE_DOUBLE:
676 double val;
677 dbus_message_iter_get_basic (iter, &val);
678 XD_DEBUG_MESSAGE ("%c %f", dtype, val);
679 return make_float (val);
682 case DBUS_TYPE_STRING:
683 case DBUS_TYPE_OBJECT_PATH:
684 case DBUS_TYPE_SIGNATURE:
686 char *val;
687 dbus_message_iter_get_basic (iter, &val);
688 XD_DEBUG_MESSAGE ("%c %s", dtype, val);
689 return build_string (val);
692 case DBUS_TYPE_ARRAY:
693 case DBUS_TYPE_VARIANT:
694 case DBUS_TYPE_STRUCT:
695 case DBUS_TYPE_DICT_ENTRY:
697 Lisp_Object result;
698 struct gcpro gcpro1;
699 DBusMessageIter subiter;
700 int subtype;
701 result = Qnil;
702 GCPRO1 (result);
703 dbus_message_iter_recurse (iter, &subiter);
704 while ((subtype = dbus_message_iter_get_arg_type (&subiter))
705 != DBUS_TYPE_INVALID)
707 result = Fcons (xd_retrieve_arg (subtype, &subiter), result);
708 dbus_message_iter_next (&subiter);
710 XD_DEBUG_MESSAGE ("%c %s", dtype, SDATA (format2 ("%s", result, Qnil)));
711 RETURN_UNGCPRO (Fnreverse (result));
714 default:
715 XD_DEBUG_MESSAGE ("DBusType '%c' not supported", dtype);
716 return Qnil;
720 /* Initialize D-Bus connection. BUS is either a Lisp symbol, :system
721 or :session, or a string denoting the bus address. It tells which
722 D-Bus to initialize. If RAISE_ERROR is non-zero, signal an error
723 when the connection cannot be initialized. */
724 static DBusConnection *
725 xd_initialize (Lisp_Object bus, int raise_error)
727 DBusConnection *connection;
728 DBusError derror;
730 /* Parameter check. */
731 if (!STRINGP (bus))
733 CHECK_SYMBOL (bus);
734 if (!(EQ (bus, QCdbus_system_bus) || EQ (bus, QCdbus_session_bus)))
736 if (raise_error)
737 XD_SIGNAL2 (build_string ("Wrong bus name"), bus);
738 else
739 return NULL;
742 /* We do not want to have an autolaunch for the session bus. */
743 if (EQ (bus, QCdbus_session_bus)
744 && getenv ("DBUS_SESSION_BUS_ADDRESS") == NULL)
746 if (raise_error)
747 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
748 else
749 return NULL;
753 /* Open a connection to the bus. */
754 dbus_error_init (&derror);
756 if (STRINGP (bus))
757 connection = dbus_connection_open (SDATA (bus), &derror);
758 else
759 if (EQ (bus, QCdbus_system_bus))
760 connection = dbus_bus_get (DBUS_BUS_SYSTEM, &derror);
761 else
762 connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
764 if (dbus_error_is_set (&derror))
766 if (raise_error)
767 XD_ERROR (derror);
768 else
769 connection = NULL;
772 /* If it is not the system or session bus, we must register
773 ourselves. Otherwise, we have called dbus_bus_get, which has
774 configured us to exit if the connection closes - we undo this
775 setting. */
776 if (connection != NULL)
778 if (STRINGP (bus))
779 dbus_bus_register (connection, &derror);
780 else
781 dbus_connection_set_exit_on_disconnect (connection, FALSE);
784 if (dbus_error_is_set (&derror))
786 if (raise_error)
787 XD_ERROR (derror);
788 else
789 connection = NULL;
792 if (connection == NULL && raise_error)
793 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
795 /* Cleanup. */
796 dbus_error_free (&derror);
798 /* Return the result. */
799 return connection;
802 /* Return the file descriptor for WATCH, -1 if not found. */
803 static int
804 xd_find_watch_fd (DBusWatch *watch)
806 #if HAVE_DBUS_WATCH_GET_UNIX_FD
807 /* TODO: Reverse these on Win32, which prefers the opposite. */
808 int fd = dbus_watch_get_unix_fd (watch);
809 if (fd == -1)
810 fd = dbus_watch_get_socket (watch);
811 #else
812 int fd = dbus_watch_get_fd (watch);
813 #endif
814 return fd;
817 /* Prototype. */
818 static void
819 xd_read_queued_messages (int fd, void *data, int for_read);
821 /* Start monitoring WATCH for possible I/O. */
822 static dbus_bool_t
823 xd_add_watch (DBusWatch *watch, void *data)
825 unsigned int flags = dbus_watch_get_flags (watch);
826 int fd = xd_find_watch_fd (watch);
828 XD_DEBUG_MESSAGE ("fd %d, write %d, enabled %d",
829 fd, flags & DBUS_WATCH_WRITABLE,
830 dbus_watch_get_enabled (watch));
832 if (fd == -1)
833 return FALSE;
835 if (dbus_watch_get_enabled (watch))
837 if (flags & DBUS_WATCH_WRITABLE)
838 add_write_fd (fd, xd_read_queued_messages, data);
839 if (flags & DBUS_WATCH_READABLE)
840 add_read_fd (fd, xd_read_queued_messages, data);
842 return TRUE;
845 /* Stop monitoring WATCH for possible I/O.
846 DATA is the used bus, either a string or QCdbus_system_bus or
847 QCdbus_session_bus. */
848 static void
849 xd_remove_watch (DBusWatch *watch, void *data)
851 unsigned int flags = dbus_watch_get_flags (watch);
852 int fd = xd_find_watch_fd (watch);
854 XD_DEBUG_MESSAGE ("fd %d", fd);
856 if (fd == -1)
857 return;
859 /* Unset session environment. */
860 if (data != NULL && data == (void*) XHASH (QCdbus_session_bus))
862 XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
863 unsetenv ("DBUS_SESSION_BUS_ADDRESS");
866 if (flags & DBUS_WATCH_WRITABLE)
867 delete_write_fd (fd);
868 if (flags & DBUS_WATCH_READABLE)
869 delete_read_fd (fd);
872 /* Toggle monitoring WATCH for possible I/O. */
873 static void
874 xd_toggle_watch (DBusWatch *watch, void *data)
876 if (dbus_watch_get_enabled (watch))
877 xd_add_watch (watch, data);
878 else
879 xd_remove_watch (watch, data);
882 DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0,
883 doc: /* Initialize connection to D-Bus BUS. */)
884 (Lisp_Object bus)
886 DBusConnection *connection;
888 /* Open a connection to the bus. */
889 connection = xd_initialize (bus, TRUE);
891 /* Add the watch functions. We pass also the bus as data, in order
892 to distinguish between the busses in xd_remove_watch. */
893 if (!dbus_connection_set_watch_functions (connection,
894 xd_add_watch,
895 xd_remove_watch,
896 xd_toggle_watch,
897 (void*) XHASH (bus), NULL))
898 XD_SIGNAL1 (build_string ("Cannot add watch functions"));
900 /* Add bus to list of registered buses. */
901 Vdbus_registered_buses = Fcons (bus, Vdbus_registered_buses);
903 /* We do not want to abort. */
904 putenv ("DBUS_FATAL_WARNINGS=0");
906 /* Return. */
907 return Qnil;
910 DEFUN ("dbus-close-bus", Fdbus_close_bus, Sdbus_close_bus, 1, 1, 0,
911 doc: /* Close connection to D-Bus BUS. */)
912 (Lisp_Object bus)
914 DBusConnection *connection;
916 /* Open a connection to the bus. */
917 connection = xd_initialize (bus, TRUE);
919 /* Decrement reference count to the bus. */
920 dbus_connection_unref (connection);
922 /* Remove bus from list of registered buses. */
923 Vdbus_registered_buses = Fdelete (bus, Vdbus_registered_buses);
925 /* Return. */
926 return Qnil;
929 DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name,
930 1, 1, 0,
931 doc: /* Return the unique name of Emacs registered at D-Bus BUS. */)
932 (Lisp_Object bus)
934 DBusConnection *connection;
935 const char *name;
937 /* Open a connection to the bus. */
938 connection = xd_initialize (bus, TRUE);
940 /* Request the name. */
941 name = dbus_bus_get_unique_name (connection);
942 if (name == NULL)
943 XD_SIGNAL1 (build_string ("No unique name available"));
945 /* Return. */
946 return build_string (name);
949 DEFUN ("dbus-call-method", Fdbus_call_method, Sdbus_call_method, 5, MANY, 0,
950 doc: /* Call METHOD on the D-Bus BUS.
952 BUS is either a Lisp symbol, `:system' or `:session', or a string
953 denoting the bus address.
955 SERVICE is the D-Bus service name to be used. PATH is the D-Bus
956 object path SERVICE is registered at. INTERFACE is an interface
957 offered by SERVICE. It must provide METHOD.
959 If the parameter `:timeout' is given, the following integer TIMEOUT
960 specifies the maximum number of milliseconds the method call must
961 return. The default value is 25,000. If the method call doesn't
962 return in time, a D-Bus error is raised.
964 All other arguments ARGS are passed to METHOD as arguments. They are
965 converted into D-Bus types via the following rules:
967 t and nil => DBUS_TYPE_BOOLEAN
968 number => DBUS_TYPE_UINT32
969 integer => DBUS_TYPE_INT32
970 float => DBUS_TYPE_DOUBLE
971 string => DBUS_TYPE_STRING
972 list => DBUS_TYPE_ARRAY
974 All arguments can be preceded by a type symbol. For details about
975 type symbols, see Info node `(dbus)Type Conversion'.
977 `dbus-call-method' returns the resulting values of METHOD as a list of
978 Lisp objects. The type conversion happens the other direction as for
979 input arguments. It follows the mapping rules:
981 DBUS_TYPE_BOOLEAN => t or nil
982 DBUS_TYPE_BYTE => number
983 DBUS_TYPE_UINT16 => number
984 DBUS_TYPE_INT16 => integer
985 DBUS_TYPE_UINT32 => number or float
986 DBUS_TYPE_INT32 => integer or float
987 DBUS_TYPE_UINT64 => number or float
988 DBUS_TYPE_INT64 => integer or float
989 DBUS_TYPE_DOUBLE => float
990 DBUS_TYPE_STRING => string
991 DBUS_TYPE_OBJECT_PATH => string
992 DBUS_TYPE_SIGNATURE => string
993 DBUS_TYPE_ARRAY => list
994 DBUS_TYPE_VARIANT => list
995 DBUS_TYPE_STRUCT => list
996 DBUS_TYPE_DICT_ENTRY => list
998 Example:
1000 \(dbus-call-method
1001 :session "org.gnome.seahorse" "/org/gnome/seahorse/keys/openpgp"
1002 "org.gnome.seahorse.Keys" "GetKeyField"
1003 "openpgp:657984B8C7A966DD" "simple-name")
1005 => (t ("Philip R. Zimmermann"))
1007 If the result of the METHOD call is just one value, the converted Lisp
1008 object is returned instead of a list containing this single Lisp object.
1010 \(dbus-call-method
1011 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer"
1012 "org.freedesktop.Hal.Device" "GetPropertyString"
1013 "system.kernel.machine")
1015 => "i686"
1017 usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &optional :timeout TIMEOUT &rest ARGS) */)
1018 (int nargs, register Lisp_Object *args)
1020 Lisp_Object bus, service, path, interface, method;
1021 Lisp_Object result;
1022 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
1023 DBusConnection *connection;
1024 DBusMessage *dmessage;
1025 DBusMessage *reply;
1026 DBusMessageIter iter;
1027 DBusError derror;
1028 unsigned int dtype;
1029 int timeout = -1;
1030 int i = 5;
1031 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1033 /* Check parameters. */
1034 bus = args[0];
1035 service = args[1];
1036 path = args[2];
1037 interface = args[3];
1038 method = args[4];
1040 CHECK_STRING (service);
1041 CHECK_STRING (path);
1042 CHECK_STRING (interface);
1043 CHECK_STRING (method);
1044 GCPRO5 (bus, service, path, interface, method);
1046 XD_DEBUG_MESSAGE ("%s %s %s %s",
1047 SDATA (service),
1048 SDATA (path),
1049 SDATA (interface),
1050 SDATA (method));
1052 /* Open a connection to the bus. */
1053 connection = xd_initialize (bus, TRUE);
1055 /* Create the message. */
1056 dmessage = dbus_message_new_method_call (SDATA (service),
1057 SDATA (path),
1058 SDATA (interface),
1059 SDATA (method));
1060 UNGCPRO;
1061 if (dmessage == NULL)
1062 XD_SIGNAL1 (build_string ("Unable to create a new message"));
1064 /* Check for timeout parameter. */
1065 if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
1067 CHECK_NATNUM (args[i+1]);
1068 timeout = XUINT (args[i+1]);
1069 i = i+2;
1072 /* Initialize parameter list of message. */
1073 dbus_message_iter_init_append (dmessage, &iter);
1075 /* Append parameters to the message. */
1076 for (; i < nargs; ++i)
1078 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1079 if (XD_DBUS_TYPE_P (args[i]))
1081 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1082 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1083 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-4,
1084 SDATA (format2 ("%s", args[i], Qnil)),
1085 SDATA (format2 ("%s", args[i+1], Qnil)));
1086 ++i;
1088 else
1090 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1091 XD_DEBUG_MESSAGE ("Parameter%d %s", i-4,
1092 SDATA (format2 ("%s", args[i], Qnil)));
1095 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1096 indication that there is no parent type. */
1097 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1099 xd_append_arg (dtype, args[i], &iter);
1102 /* Send the message. */
1103 dbus_error_init (&derror);
1104 reply = dbus_connection_send_with_reply_and_block (connection,
1105 dmessage,
1106 timeout,
1107 &derror);
1109 if (dbus_error_is_set (&derror))
1110 XD_ERROR (derror);
1112 if (reply == NULL)
1113 XD_SIGNAL1 (build_string ("No reply"));
1115 XD_DEBUG_MESSAGE ("Message sent");
1117 /* Collect the results. */
1118 result = Qnil;
1119 GCPRO1 (result);
1121 if (dbus_message_iter_init (reply, &iter))
1123 /* Loop over the parameters of the D-Bus reply message. Construct a
1124 Lisp list, which is returned by `dbus-call-method'. */
1125 while ((dtype = dbus_message_iter_get_arg_type (&iter))
1126 != DBUS_TYPE_INVALID)
1128 result = Fcons (xd_retrieve_arg (dtype, &iter), result);
1129 dbus_message_iter_next (&iter);
1132 else
1134 /* No arguments: just return nil. */
1137 /* Cleanup. */
1138 dbus_error_free (&derror);
1139 dbus_message_unref (dmessage);
1140 dbus_message_unref (reply);
1142 /* Return the result. If there is only one single Lisp object,
1143 return it as-it-is, otherwise return the reversed list. */
1144 if (XUINT (Flength (result)) == 1)
1145 RETURN_UNGCPRO (CAR_SAFE (result));
1146 else
1147 RETURN_UNGCPRO (Fnreverse (result));
1150 DEFUN ("dbus-call-method-asynchronously", Fdbus_call_method_asynchronously,
1151 Sdbus_call_method_asynchronously, 6, MANY, 0,
1152 doc: /* Call METHOD on the D-Bus BUS asynchronously.
1154 BUS is either a Lisp symbol, `:system' or `:session', or a string
1155 denoting the bus address.
1157 SERVICE is the D-Bus service name to be used. PATH is the D-Bus
1158 object path SERVICE is registered at. INTERFACE is an interface
1159 offered by SERVICE. It must provide METHOD.
1161 HANDLER is a Lisp function, which is called when the corresponding
1162 return message has arrived. If HANDLER is nil, no return message will
1163 be expected.
1165 If the parameter `:timeout' is given, the following integer TIMEOUT
1166 specifies the maximum number of milliseconds the method call must
1167 return. The default value is 25,000. If the method call doesn't
1168 return in time, a D-Bus error is raised.
1170 All other arguments ARGS are passed to METHOD as arguments. They are
1171 converted into D-Bus types via the following rules:
1173 t and nil => DBUS_TYPE_BOOLEAN
1174 number => DBUS_TYPE_UINT32
1175 integer => DBUS_TYPE_INT32
1176 float => DBUS_TYPE_DOUBLE
1177 string => DBUS_TYPE_STRING
1178 list => DBUS_TYPE_ARRAY
1180 All arguments can be preceded by a type symbol. For details about
1181 type symbols, see Info node `(dbus)Type Conversion'.
1183 Unless HANDLER is nil, the function returns a key into the hash table
1184 `dbus-registered-objects-table'. The corresponding entry in the hash
1185 table is removed, when the return message has been arrived, and
1186 HANDLER is called.
1188 Example:
1190 \(dbus-call-method-asynchronously
1191 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer"
1192 "org.freedesktop.Hal.Device" "GetPropertyString" 'message
1193 "system.kernel.machine")
1195 => (:system 2)
1197 -| i686
1199 usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLER &optional :timeout TIMEOUT &rest ARGS) */)
1200 (int nargs, register Lisp_Object *args)
1202 Lisp_Object bus, service, path, interface, method, handler;
1203 Lisp_Object result;
1204 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
1205 DBusConnection *connection;
1206 DBusMessage *dmessage;
1207 DBusMessageIter iter;
1208 unsigned int dtype;
1209 int timeout = -1;
1210 int i = 6;
1211 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1213 /* Check parameters. */
1214 bus = args[0];
1215 service = args[1];
1216 path = args[2];
1217 interface = args[3];
1218 method = args[4];
1219 handler = args[5];
1221 CHECK_STRING (service);
1222 CHECK_STRING (path);
1223 CHECK_STRING (interface);
1224 CHECK_STRING (method);
1225 if (!NILP (handler) && !FUNCTIONP (handler))
1226 wrong_type_argument (intern ("functionp"), handler);
1227 GCPRO6 (bus, service, path, interface, method, handler);
1229 XD_DEBUG_MESSAGE ("%s %s %s %s",
1230 SDATA (service),
1231 SDATA (path),
1232 SDATA (interface),
1233 SDATA (method));
1235 /* Open a connection to the bus. */
1236 connection = xd_initialize (bus, TRUE);
1238 /* Create the message. */
1239 dmessage = dbus_message_new_method_call (SDATA (service),
1240 SDATA (path),
1241 SDATA (interface),
1242 SDATA (method));
1243 if (dmessage == NULL)
1244 XD_SIGNAL1 (build_string ("Unable to create a new message"));
1246 /* Check for timeout parameter. */
1247 if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
1249 CHECK_NATNUM (args[i+1]);
1250 timeout = XUINT (args[i+1]);
1251 i = i+2;
1254 /* Initialize parameter list of message. */
1255 dbus_message_iter_init_append (dmessage, &iter);
1257 /* Append parameters to the message. */
1258 for (; i < nargs; ++i)
1260 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1261 if (XD_DBUS_TYPE_P (args[i]))
1263 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1264 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1265 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-4,
1266 SDATA (format2 ("%s", args[i], Qnil)),
1267 SDATA (format2 ("%s", args[i+1], Qnil)));
1268 ++i;
1270 else
1272 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1273 XD_DEBUG_MESSAGE ("Parameter%d %s", i-4,
1274 SDATA (format2 ("%s", args[i], Qnil)));
1277 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1278 indication that there is no parent type. */
1279 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1281 xd_append_arg (dtype, args[i], &iter);
1284 if (!NILP (handler))
1286 /* Send the message. The message is just added to the outgoing
1287 message queue. */
1288 if (!dbus_connection_send_with_reply (connection, dmessage,
1289 NULL, timeout))
1290 XD_SIGNAL1 (build_string ("Cannot send message"));
1292 /* The result is the key in Vdbus_registered_objects_table. */
1293 result = (list2 (bus, make_number (dbus_message_get_serial (dmessage))));
1295 /* Create a hash table entry. */
1296 Fputhash (result, handler, Vdbus_registered_objects_table);
1298 else
1300 /* Send the message. The message is just added to the outgoing
1301 message queue. */
1302 if (!dbus_connection_send (connection, dmessage, NULL))
1303 XD_SIGNAL1 (build_string ("Cannot send message"));
1305 result = Qnil;
1308 XD_DEBUG_MESSAGE ("Message sent");
1310 /* Cleanup. */
1311 dbus_message_unref (dmessage);
1313 /* Return the result. */
1314 RETURN_UNGCPRO (result);
1317 DEFUN ("dbus-method-return-internal", Fdbus_method_return_internal,
1318 Sdbus_method_return_internal,
1319 3, MANY, 0,
1320 doc: /* Return for message SERIAL on the D-Bus BUS.
1321 This is an internal function, it shall not be used outside dbus.el.
1323 usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */)
1324 (int nargs, register Lisp_Object *args)
1326 Lisp_Object bus, serial, service;
1327 struct gcpro gcpro1, gcpro2, gcpro3;
1328 DBusConnection *connection;
1329 DBusMessage *dmessage;
1330 DBusMessageIter iter;
1331 unsigned int dtype;
1332 int i;
1333 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1335 /* Check parameters. */
1336 bus = args[0];
1337 serial = args[1];
1338 service = args[2];
1340 CHECK_NUMBER (serial);
1341 CHECK_STRING (service);
1342 GCPRO3 (bus, serial, service);
1344 XD_DEBUG_MESSAGE ("%lu %s ", (unsigned long) XUINT (serial), SDATA (service));
1346 /* Open a connection to the bus. */
1347 connection = xd_initialize (bus, TRUE);
1349 /* Create the message. */
1350 dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
1351 if ((dmessage == NULL)
1352 || (!dbus_message_set_reply_serial (dmessage, XUINT (serial)))
1353 || (!dbus_message_set_destination (dmessage, SDATA (service))))
1355 UNGCPRO;
1356 XD_SIGNAL1 (build_string ("Unable to create a return message"));
1359 UNGCPRO;
1361 /* Initialize parameter list of message. */
1362 dbus_message_iter_init_append (dmessage, &iter);
1364 /* Append parameters to the message. */
1365 for (i = 3; i < nargs; ++i)
1367 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1368 if (XD_DBUS_TYPE_P (args[i]))
1370 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1371 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1372 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-2,
1373 SDATA (format2 ("%s", args[i], Qnil)),
1374 SDATA (format2 ("%s", args[i+1], Qnil)));
1375 ++i;
1377 else
1379 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1380 XD_DEBUG_MESSAGE ("Parameter%d %s", i-2,
1381 SDATA (format2 ("%s", args[i], Qnil)));
1384 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1385 indication that there is no parent type. */
1386 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1388 xd_append_arg (dtype, args[i], &iter);
1391 /* Send the message. The message is just added to the outgoing
1392 message queue. */
1393 if (!dbus_connection_send (connection, dmessage, NULL))
1394 XD_SIGNAL1 (build_string ("Cannot send message"));
1396 XD_DEBUG_MESSAGE ("Message sent");
1398 /* Cleanup. */
1399 dbus_message_unref (dmessage);
1401 /* Return. */
1402 return Qt;
1405 DEFUN ("dbus-method-error-internal", Fdbus_method_error_internal,
1406 Sdbus_method_error_internal,
1407 3, MANY, 0,
1408 doc: /* Return error message for message SERIAL on the D-Bus BUS.
1409 This is an internal function, it shall not be used outside dbus.el.
1411 usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */)
1412 (int nargs, register Lisp_Object *args)
1414 Lisp_Object bus, serial, service;
1415 struct gcpro gcpro1, gcpro2, gcpro3;
1416 DBusConnection *connection;
1417 DBusMessage *dmessage;
1418 DBusMessageIter iter;
1419 unsigned int dtype;
1420 int i;
1421 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1423 /* Check parameters. */
1424 bus = args[0];
1425 serial = args[1];
1426 service = args[2];
1428 CHECK_NUMBER (serial);
1429 CHECK_STRING (service);
1430 GCPRO3 (bus, serial, service);
1432 XD_DEBUG_MESSAGE ("%lu %s ", (unsigned long) XUINT (serial), SDATA (service));
1434 /* Open a connection to the bus. */
1435 connection = xd_initialize (bus, TRUE);
1437 /* Create the message. */
1438 dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
1439 if ((dmessage == NULL)
1440 || (!dbus_message_set_error_name (dmessage, DBUS_ERROR_FAILED))
1441 || (!dbus_message_set_reply_serial (dmessage, XUINT (serial)))
1442 || (!dbus_message_set_destination (dmessage, SDATA (service))))
1444 UNGCPRO;
1445 XD_SIGNAL1 (build_string ("Unable to create a error message"));
1448 UNGCPRO;
1450 /* Initialize parameter list of message. */
1451 dbus_message_iter_init_append (dmessage, &iter);
1453 /* Append parameters to the message. */
1454 for (i = 3; i < nargs; ++i)
1456 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1457 if (XD_DBUS_TYPE_P (args[i]))
1459 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1460 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1461 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-2,
1462 SDATA (format2 ("%s", args[i], Qnil)),
1463 SDATA (format2 ("%s", args[i+1], Qnil)));
1464 ++i;
1466 else
1468 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1469 XD_DEBUG_MESSAGE ("Parameter%d %s", i-2,
1470 SDATA (format2 ("%s", args[i], Qnil)));
1473 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1474 indication that there is no parent type. */
1475 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1477 xd_append_arg (dtype, args[i], &iter);
1480 /* Send the message. The message is just added to the outgoing
1481 message queue. */
1482 if (!dbus_connection_send (connection, dmessage, NULL))
1483 XD_SIGNAL1 (build_string ("Cannot send message"));
1485 XD_DEBUG_MESSAGE ("Message sent");
1487 /* Cleanup. */
1488 dbus_message_unref (dmessage);
1490 /* Return. */
1491 return Qt;
1494 DEFUN ("dbus-send-signal", Fdbus_send_signal, Sdbus_send_signal, 5, MANY, 0,
1495 doc: /* Send signal SIGNAL on the D-Bus BUS.
1497 BUS is either a Lisp symbol, `:system' or `:session', or a string
1498 denoting the bus address.
1500 SERVICE is the D-Bus service name SIGNAL is sent from. PATH is the
1501 D-Bus object path SERVICE is registered at. INTERFACE is an interface
1502 offered by SERVICE. It must provide signal SIGNAL.
1504 All other arguments ARGS are passed to SIGNAL as arguments. They are
1505 converted into D-Bus types via the following rules:
1507 t and nil => DBUS_TYPE_BOOLEAN
1508 number => DBUS_TYPE_UINT32
1509 integer => DBUS_TYPE_INT32
1510 float => DBUS_TYPE_DOUBLE
1511 string => DBUS_TYPE_STRING
1512 list => DBUS_TYPE_ARRAY
1514 All arguments can be preceded by a type symbol. For details about
1515 type symbols, see Info node `(dbus)Type Conversion'.
1517 Example:
1519 \(dbus-send-signal
1520 :session "org.gnu.Emacs" "/org/gnu/Emacs"
1521 "org.gnu.Emacs.FileManager" "FileModified" "/home/albinus/.emacs")
1523 usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
1524 (int nargs, register Lisp_Object *args)
1526 Lisp_Object bus, service, path, interface, signal;
1527 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
1528 DBusConnection *connection;
1529 DBusMessage *dmessage;
1530 DBusMessageIter iter;
1531 unsigned int dtype;
1532 int i;
1533 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1535 /* Check parameters. */
1536 bus = args[0];
1537 service = args[1];
1538 path = args[2];
1539 interface = args[3];
1540 signal = args[4];
1542 CHECK_STRING (service);
1543 CHECK_STRING (path);
1544 CHECK_STRING (interface);
1545 CHECK_STRING (signal);
1546 GCPRO5 (bus, service, path, interface, signal);
1548 XD_DEBUG_MESSAGE ("%s %s %s %s",
1549 SDATA (service),
1550 SDATA (path),
1551 SDATA (interface),
1552 SDATA (signal));
1554 /* Open a connection to the bus. */
1555 connection = xd_initialize (bus, TRUE);
1557 /* Create the message. */
1558 dmessage = dbus_message_new_signal (SDATA (path),
1559 SDATA (interface),
1560 SDATA (signal));
1561 UNGCPRO;
1562 if (dmessage == NULL)
1563 XD_SIGNAL1 (build_string ("Unable to create a new message"));
1565 /* Initialize parameter list of message. */
1566 dbus_message_iter_init_append (dmessage, &iter);
1568 /* Append parameters to the message. */
1569 for (i = 5; i < nargs; ++i)
1571 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1572 if (XD_DBUS_TYPE_P (args[i]))
1574 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1575 XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1576 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-4,
1577 SDATA (format2 ("%s", args[i], Qnil)),
1578 SDATA (format2 ("%s", args[i+1], Qnil)));
1579 ++i;
1581 else
1583 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1584 XD_DEBUG_MESSAGE ("Parameter%d %s", i-4,
1585 SDATA (format2 ("%s", args[i], Qnil)));
1588 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1589 indication that there is no parent type. */
1590 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1592 xd_append_arg (dtype, args[i], &iter);
1595 /* Send the message. The message is just added to the outgoing
1596 message queue. */
1597 if (!dbus_connection_send (connection, dmessage, NULL))
1598 XD_SIGNAL1 (build_string ("Cannot send message"));
1600 XD_DEBUG_MESSAGE ("Signal sent");
1602 /* Cleanup. */
1603 dbus_message_unref (dmessage);
1605 /* Return. */
1606 return Qt;
1609 /* Read one queued incoming message of the D-Bus BUS.
1610 BUS is either a Lisp symbol, :system or :session, or a string denoting
1611 the bus address. */
1612 static void
1613 xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
1615 Lisp_Object args, key, value;
1616 struct gcpro gcpro1;
1617 struct input_event event;
1618 DBusMessage *dmessage;
1619 DBusMessageIter iter;
1620 unsigned int dtype;
1621 int mtype, serial;
1622 const char *uname, *path, *interface, *member;
1624 dmessage = dbus_connection_pop_message (connection);
1626 /* Return if there is no queued message. */
1627 if (dmessage == NULL)
1628 return;
1630 /* Collect the parameters. */
1631 args = Qnil;
1632 GCPRO1 (args);
1634 /* Loop over the resulting parameters. Construct a list. */
1635 if (dbus_message_iter_init (dmessage, &iter))
1637 while ((dtype = dbus_message_iter_get_arg_type (&iter))
1638 != DBUS_TYPE_INVALID)
1640 args = Fcons (xd_retrieve_arg (dtype, &iter), args);
1641 dbus_message_iter_next (&iter);
1643 /* The arguments are stored in reverse order. Reorder them. */
1644 args = Fnreverse (args);
1647 /* Read message type, message serial, unique name, object path,
1648 interface and member from the message. */
1649 mtype = dbus_message_get_type (dmessage);
1650 serial =
1651 ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1652 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1653 ? dbus_message_get_reply_serial (dmessage)
1654 : dbus_message_get_serial (dmessage);
1655 uname = dbus_message_get_sender (dmessage);
1656 path = dbus_message_get_path (dmessage);
1657 interface = dbus_message_get_interface (dmessage);
1658 member = dbus_message_get_member (dmessage);
1660 XD_DEBUG_MESSAGE ("Event received: %s %d %s %s %s %s %s",
1661 (mtype == DBUS_MESSAGE_TYPE_INVALID)
1662 ? "DBUS_MESSAGE_TYPE_INVALID"
1663 : (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1664 ? "DBUS_MESSAGE_TYPE_METHOD_CALL"
1665 : (mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1666 ? "DBUS_MESSAGE_TYPE_METHOD_RETURN"
1667 : (mtype == DBUS_MESSAGE_TYPE_ERROR)
1668 ? "DBUS_MESSAGE_TYPE_ERROR"
1669 : "DBUS_MESSAGE_TYPE_SIGNAL",
1670 serial, uname, path, interface, member,
1671 SDATA (format2 ("%s", args, Qnil)));
1673 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1674 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1676 /* Search for a registered function of the message. */
1677 key = list2 (bus, make_number (serial));
1678 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1680 /* There shall be exactly one entry. Construct an event. */
1681 if (NILP (value))
1682 goto cleanup;
1684 /* Remove the entry. */
1685 Fremhash (key, Vdbus_registered_objects_table);
1687 /* Construct an event. */
1688 EVENT_INIT (event);
1689 event.kind = DBUS_EVENT;
1690 event.frame_or_window = Qnil;
1691 event.arg = Fcons (value, args);
1694 else /* (mtype != DBUS_MESSAGE_TYPE_METHOD_RETURN) */
1696 /* Vdbus_registered_objects_table requires non-nil interface and
1697 member. */
1698 if ((interface == NULL) || (member == NULL))
1699 goto cleanup;
1701 /* Search for a registered function of the message. */
1702 key = list3 (bus, build_string (interface), build_string (member));
1703 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1705 /* Loop over the registered functions. Construct an event. */
1706 while (!NILP (value))
1708 key = CAR_SAFE (value);
1709 /* key has the structure (UNAME SERVICE PATH HANDLER). */
1710 if (((uname == NULL)
1711 || (NILP (CAR_SAFE (key)))
1712 || (strcmp (uname, SDATA (CAR_SAFE (key))) == 0))
1713 && ((path == NULL)
1714 || (NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (key)))))
1715 || (strcmp (path,
1716 SDATA (CAR_SAFE (CDR_SAFE (CDR_SAFE (key)))))
1717 == 0))
1718 && (!NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))))))
1720 EVENT_INIT (event);
1721 event.kind = DBUS_EVENT;
1722 event.frame_or_window = Qnil;
1723 event.arg = Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))),
1724 args);
1725 break;
1727 value = CDR_SAFE (value);
1730 if (NILP (value))
1731 goto cleanup;
1734 /* Add type, serial, uname, path, interface and member to the event. */
1735 event.arg = Fcons ((member == NULL ? Qnil : build_string (member)),
1736 event.arg);
1737 event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)),
1738 event.arg);
1739 event.arg = Fcons ((path == NULL ? Qnil : build_string (path)),
1740 event.arg);
1741 event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)),
1742 event.arg);
1743 event.arg = Fcons (make_number (serial), event.arg);
1744 event.arg = Fcons (make_number (mtype), event.arg);
1746 /* Add the bus symbol to the event. */
1747 event.arg = Fcons (bus, event.arg);
1749 /* Store it into the input event queue. */
1750 kbd_buffer_store_event (&event);
1752 XD_DEBUG_MESSAGE ("Event stored: %s",
1753 SDATA (format2 ("%s", event.arg, Qnil)));
1755 /* Cleanup. */
1756 cleanup:
1757 dbus_message_unref (dmessage);
1759 UNGCPRO;
1762 /* Read queued incoming messages of the D-Bus BUS.
1763 BUS is either a Lisp symbol, :system or :session, or a string denoting
1764 the bus address. */
1765 static Lisp_Object
1766 xd_read_message (Lisp_Object bus)
1768 /* Open a connection to the bus. */
1769 DBusConnection *connection = xd_initialize (bus, TRUE);
1771 /* Non blocking read of the next available message. */
1772 dbus_connection_read_write (connection, 0);
1774 while (dbus_connection_get_dispatch_status (connection)
1775 != DBUS_DISPATCH_COMPLETE)
1776 xd_read_message_1 (connection, bus);
1777 return Qnil;
1780 /* Callback called when something is ready to read or write. */
1781 static void
1782 xd_read_queued_messages (int fd, void *data, int for_read)
1784 Lisp_Object busp = Vdbus_registered_buses;
1785 Lisp_Object bus = Qnil;
1787 /* Find bus related to fd. */
1788 if (data != NULL)
1789 while (!NILP (busp))
1791 if (data == (void*) XHASH (CAR_SAFE (busp)))
1792 bus = CAR_SAFE (busp);
1793 busp = CDR_SAFE (busp);
1796 if (NILP(bus))
1797 return;
1799 /* We ignore all Lisp errors during the call. */
1800 xd_in_read_queued_messages = 1;
1801 internal_catch (Qdbus_error, xd_read_message, bus);
1802 xd_in_read_queued_messages = 0;
1805 DEFUN ("dbus-register-signal", Fdbus_register_signal, Sdbus_register_signal,
1806 6, MANY, 0,
1807 doc: /* Register for signal SIGNAL on the D-Bus BUS.
1809 BUS is either a Lisp symbol, `:system' or `:session', or a string
1810 denoting the bus address.
1812 SERVICE is the D-Bus service name used by the sending D-Bus object.
1813 It can be either a known name or the unique name of the D-Bus object
1814 sending the signal. When SERVICE is nil, related signals from all
1815 D-Bus objects shall be accepted.
1817 PATH is the D-Bus object path SERVICE is registered. It can also be
1818 nil if the path name of incoming signals shall not be checked.
1820 INTERFACE is an interface offered by SERVICE. It must provide SIGNAL.
1821 HANDLER is a Lisp function to be called when the signal is received.
1822 It must accept as arguments the values SIGNAL is sending.
1824 All other arguments ARGS, if specified, must be strings. They stand
1825 for the respective arguments of the signal in their order, and are
1826 used for filtering as well. A nil argument might be used to preserve
1827 the order.
1829 INTERFACE, SIGNAL and HANDLER must not be nil. Example:
1831 \(defun my-signal-handler (device)
1832 (message "Device %s added" device))
1834 \(dbus-register-signal
1835 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/Manager"
1836 "org.freedesktop.Hal.Manager" "DeviceAdded" 'my-signal-handler)
1838 => ((:system "org.freedesktop.Hal.Manager" "DeviceAdded")
1839 ("org.freedesktop.Hal" "/org/freedesktop/Hal/Manager" my-signal-handler))
1841 `dbus-register-signal' returns an object, which can be used in
1842 `dbus-unregister-object' for removing the registration.
1844 usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARGS) */)
1845 (int nargs, register Lisp_Object *args)
1847 Lisp_Object bus, service, path, interface, signal, handler;
1848 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
1849 Lisp_Object uname, key, key1, value;
1850 DBusConnection *connection;
1851 int i;
1852 char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
1853 char x[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
1854 DBusError derror;
1856 /* Check parameters. */
1857 bus = args[0];
1858 service = args[1];
1859 path = args[2];
1860 interface = args[3];
1861 signal = args[4];
1862 handler = args[5];
1864 if (!NILP (service)) CHECK_STRING (service);
1865 if (!NILP (path)) CHECK_STRING (path);
1866 CHECK_STRING (interface);
1867 CHECK_STRING (signal);
1868 if (!FUNCTIONP (handler))
1869 wrong_type_argument (intern ("functionp"), handler);
1870 GCPRO6 (bus, service, path, interface, signal, handler);
1872 /* Retrieve unique name of service. If service is a known name, we
1873 will register for the corresponding unique name, if any. Signals
1874 are sent always with the unique name as sender. Note: the unique
1875 name of "org.freedesktop.DBus" is that string itself. */
1876 if ((STRINGP (service))
1877 && (SBYTES (service) > 0)
1878 && (strcmp (SDATA (service), DBUS_SERVICE_DBUS) != 0)
1879 && (strncmp (SDATA (service), ":", 1) != 0))
1881 uname = call2 (intern ("dbus-get-name-owner"), bus, service);
1882 /* When there is no unique name, we mark it with an empty
1883 string. */
1884 if (NILP (uname))
1885 uname = empty_unibyte_string;
1887 else
1888 uname = service;
1890 /* Create a matching rule if the unique name exists (when no
1891 wildcard). */
1892 if (NILP (uname) || (SBYTES (uname) > 0))
1894 /* Open a connection to the bus. */
1895 connection = xd_initialize (bus, TRUE);
1897 /* Create a rule to receive related signals. */
1898 sprintf (rule,
1899 "type='signal',interface='%s',member='%s'",
1900 SDATA (interface),
1901 SDATA (signal));
1903 /* Add unique name and path to the rule if they are non-nil. */
1904 if (!NILP (uname))
1906 sprintf (x, ",sender='%s'", SDATA (uname));
1907 strcat (rule, x);
1910 if (!NILP (path))
1912 sprintf (x, ",path='%s'", SDATA (path));
1913 strcat (rule, x);
1916 /* Add arguments to the rule if they are non-nil. */
1917 for (i = 6; i < nargs; ++i)
1918 if (!NILP (args[i]))
1920 CHECK_STRING (args[i]);
1921 sprintf (x, ",arg%d='%s'", i-6, SDATA (args[i]));
1922 strcat (rule, x);
1925 /* Add the rule to the bus. */
1926 dbus_error_init (&derror);
1927 dbus_bus_add_match (connection, rule, &derror);
1928 if (dbus_error_is_set (&derror))
1930 UNGCPRO;
1931 XD_ERROR (derror);
1934 /* Cleanup. */
1935 dbus_error_free (&derror);
1937 XD_DEBUG_MESSAGE ("Matching rule \"%s\" created", rule);
1940 /* Create a hash table entry. */
1941 key = list3 (bus, interface, signal);
1942 key1 = list4 (uname, service, path, handler);
1943 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1945 if (NILP (Fmember (key1, value)))
1946 Fputhash (key, Fcons (key1, value), Vdbus_registered_objects_table);
1948 /* Return object. */
1949 RETURN_UNGCPRO (list2 (key, list3 (service, path, handler)));
1952 DEFUN ("dbus-register-method", Fdbus_register_method, Sdbus_register_method,
1953 6, 6, 0,
1954 doc: /* Register for method METHOD on the D-Bus BUS.
1956 BUS is either a Lisp symbol, `:system' or `:session', or a string
1957 denoting the bus address.
1959 SERVICE is the D-Bus service name of the D-Bus object METHOD is
1960 registered for. It must be a known name.
1962 PATH is the D-Bus object path SERVICE is registered. INTERFACE is the
1963 interface offered by SERVICE. It must provide METHOD. HANDLER is a
1964 Lisp function to be called when a method call is received. It must
1965 accept the input arguments of METHOD. The return value of HANDLER is
1966 used for composing the returning D-Bus message. */)
1967 (Lisp_Object bus, Lisp_Object service, Lisp_Object path, Lisp_Object interface, Lisp_Object method, Lisp_Object handler)
1969 Lisp_Object key, key1, value;
1970 DBusConnection *connection;
1971 int result;
1972 DBusError derror;
1974 /* Check parameters. */
1975 CHECK_STRING (service);
1976 CHECK_STRING (path);
1977 CHECK_STRING (interface);
1978 CHECK_STRING (method);
1979 if (!FUNCTIONP (handler))
1980 wrong_type_argument (intern ("functionp"), handler);
1981 /* TODO: We must check for a valid service name, otherwise there is
1982 a segmentation fault. */
1984 /* Open a connection to the bus. */
1985 connection = xd_initialize (bus, TRUE);
1987 /* Request the known name from the bus. We can ignore the result,
1988 it is set to -1 if there is an error - kind of redundancy. */
1989 dbus_error_init (&derror);
1990 result = dbus_bus_request_name (connection, SDATA (service), 0, &derror);
1991 if (dbus_error_is_set (&derror))
1992 XD_ERROR (derror);
1994 /* Create a hash table entry. We use nil for the unique name,
1995 because the method might be called from anybody. */
1996 key = list3 (bus, interface, method);
1997 key1 = list4 (Qnil, service, path, handler);
1998 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
2000 if (NILP (Fmember (key1, value)))
2001 Fputhash (key, Fcons (key1, value), Vdbus_registered_objects_table);
2003 /* Cleanup. */
2004 dbus_error_free (&derror);
2006 /* Return object. */
2007 return list2 (key, list3 (service, path, handler));
2011 void
2012 syms_of_dbusbind (void)
2015 Qdbus_init_bus = intern_c_string ("dbus-init-bus");
2016 staticpro (&Qdbus_init_bus);
2017 defsubr (&Sdbus_init_bus);
2019 Qdbus_close_bus = intern_c_string ("dbus-close-bus");
2020 staticpro (&Qdbus_close_bus);
2021 defsubr (&Sdbus_close_bus);
2023 Qdbus_get_unique_name = intern_c_string ("dbus-get-unique-name");
2024 staticpro (&Qdbus_get_unique_name);
2025 defsubr (&Sdbus_get_unique_name);
2027 Qdbus_call_method = intern_c_string ("dbus-call-method");
2028 staticpro (&Qdbus_call_method);
2029 defsubr (&Sdbus_call_method);
2031 Qdbus_call_method_asynchronously = intern_c_string ("dbus-call-method-asynchronously");
2032 staticpro (&Qdbus_call_method_asynchronously);
2033 defsubr (&Sdbus_call_method_asynchronously);
2035 Qdbus_method_return_internal = intern_c_string ("dbus-method-return-internal");
2036 staticpro (&Qdbus_method_return_internal);
2037 defsubr (&Sdbus_method_return_internal);
2039 Qdbus_method_error_internal = intern_c_string ("dbus-method-error-internal");
2040 staticpro (&Qdbus_method_error_internal);
2041 defsubr (&Sdbus_method_error_internal);
2043 Qdbus_send_signal = intern_c_string ("dbus-send-signal");
2044 staticpro (&Qdbus_send_signal);
2045 defsubr (&Sdbus_send_signal);
2047 Qdbus_register_signal = intern_c_string ("dbus-register-signal");
2048 staticpro (&Qdbus_register_signal);
2049 defsubr (&Sdbus_register_signal);
2051 Qdbus_register_method = intern_c_string ("dbus-register-method");
2052 staticpro (&Qdbus_register_method);
2053 defsubr (&Sdbus_register_method);
2055 Qdbus_error = intern_c_string ("dbus-error");
2056 staticpro (&Qdbus_error);
2057 Fput (Qdbus_error, Qerror_conditions,
2058 list2 (Qdbus_error, Qerror));
2059 Fput (Qdbus_error, Qerror_message,
2060 make_pure_c_string ("D-Bus error"));
2062 QCdbus_system_bus = intern_c_string (":system");
2063 staticpro (&QCdbus_system_bus);
2065 QCdbus_session_bus = intern_c_string (":session");
2066 staticpro (&QCdbus_session_bus);
2068 QCdbus_timeout = intern_c_string (":timeout");
2069 staticpro (&QCdbus_timeout);
2071 QCdbus_type_byte = intern_c_string (":byte");
2072 staticpro (&QCdbus_type_byte);
2074 QCdbus_type_boolean = intern_c_string (":boolean");
2075 staticpro (&QCdbus_type_boolean);
2077 QCdbus_type_int16 = intern_c_string (":int16");
2078 staticpro (&QCdbus_type_int16);
2080 QCdbus_type_uint16 = intern_c_string (":uint16");
2081 staticpro (&QCdbus_type_uint16);
2083 QCdbus_type_int32 = intern_c_string (":int32");
2084 staticpro (&QCdbus_type_int32);
2086 QCdbus_type_uint32 = intern_c_string (":uint32");
2087 staticpro (&QCdbus_type_uint32);
2089 QCdbus_type_int64 = intern_c_string (":int64");
2090 staticpro (&QCdbus_type_int64);
2092 QCdbus_type_uint64 = intern_c_string (":uint64");
2093 staticpro (&QCdbus_type_uint64);
2095 QCdbus_type_double = intern_c_string (":double");
2096 staticpro (&QCdbus_type_double);
2098 QCdbus_type_string = intern_c_string (":string");
2099 staticpro (&QCdbus_type_string);
2101 QCdbus_type_object_path = intern_c_string (":object-path");
2102 staticpro (&QCdbus_type_object_path);
2104 QCdbus_type_signature = intern_c_string (":signature");
2105 staticpro (&QCdbus_type_signature);
2107 QCdbus_type_array = intern_c_string (":array");
2108 staticpro (&QCdbus_type_array);
2110 QCdbus_type_variant = intern_c_string (":variant");
2111 staticpro (&QCdbus_type_variant);
2113 QCdbus_type_struct = intern_c_string (":struct");
2114 staticpro (&QCdbus_type_struct);
2116 QCdbus_type_dict_entry = intern_c_string (":dict-entry");
2117 staticpro (&QCdbus_type_dict_entry);
2119 DEFVAR_LISP ("dbus-registered-buses",
2120 &Vdbus_registered_buses,
2121 doc: /* List of D-Bus buses we are polling for messages. */);
2122 Vdbus_registered_buses = Qnil;
2124 DEFVAR_LISP ("dbus-registered-objects-table",
2125 &Vdbus_registered_objects_table,
2126 doc: /* Hash table of registered functions for D-Bus.
2128 There are two different uses of the hash table: for accessing
2129 registered interfaces properties, targeted by signals or method calls,
2130 and for calling handlers in case of non-blocking method call returns.
2132 In the first case, the key in the hash table is the list (BUS
2133 INTERFACE MEMBER). BUS is either a Lisp symbol, `:system' or
2134 `:session', or a string denoting the bus address. INTERFACE is a
2135 string which denotes a D-Bus interface, and MEMBER, also a string, is
2136 either a method, a signal or a property INTERFACE is offering. All
2137 arguments but BUS must not be nil.
2139 The value in the hash table is a list of quadruple lists
2140 \((UNAME SERVICE PATH OBJECT) (UNAME SERVICE PATH OBJECT) ...).
2141 SERVICE is the service name as registered, UNAME is the corresponding
2142 unique name. In case of registered methods and properties, UNAME is
2143 nil. PATH is the object path of the sending object. All of them can
2144 be nil, which means a wildcard then. OBJECT is either the handler to
2145 be called when a D-Bus message, which matches the key criteria,
2146 arrives (methods and signals), or a cons cell containing the value of
2147 the property.
2149 In the second case, the key in the hash table is the list (BUS
2150 SERIAL). BUS is either a Lisp symbol, `:system' or `:session', or a
2151 string denoting the bus address. SERIAL is the serial number of the
2152 non-blocking method call, a reply is expected. Both arguments must
2153 not be nil. The value in the hash table is HANDLER, the function to
2154 be called when the D-Bus reply message arrives. */);
2156 Lisp_Object args[2];
2157 args[0] = QCtest;
2158 args[1] = Qequal;
2159 Vdbus_registered_objects_table = Fmake_hash_table (2, args);
2162 DEFVAR_LISP ("dbus-debug", &Vdbus_debug,
2163 doc: /* If non-nil, debug messages of D-Bus bindings are raised. */);
2164 #ifdef DBUS_DEBUG
2165 Vdbus_debug = Qt;
2166 /* We can also set environment variable DBUS_VERBOSE=1 in order to
2167 see more traces. This requires libdbus-1 to be configured with
2168 --enable-verbose-mode. */
2169 #else
2170 Vdbus_debug = Qnil;
2171 #endif
2173 Fprovide (intern_c_string ("dbusbind"), Qnil);
2177 #endif /* HAVE_DBUS */
2179 /* arch-tag: 0e828477-b571-4fe4-b559-5c9211bc14b8
2180 (do not change this comment) */