1 /* Elisp bindings for D-Bus.
2 Copyright (C) 2007, 2008 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, or (at your option)
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; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA. */
26 #include <dbus/dbus.h>
29 #include "termhooks.h"
34 Lisp_Object Qdbus_get_unique_name
;
35 Lisp_Object Qdbus_call_method
;
36 Lisp_Object Qdbus_method_return_internal
;
37 Lisp_Object Qdbus_send_signal
;
38 Lisp_Object Qdbus_register_signal
;
39 Lisp_Object Qdbus_register_method
;
41 /* D-Bus error symbol. */
42 Lisp_Object Qdbus_error
;
44 /* Lisp symbols of the system and session buses. */
45 Lisp_Object QCdbus_system_bus
, QCdbus_session_bus
;
47 /* Lisp symbols of D-Bus types. */
48 Lisp_Object QCdbus_type_byte
, QCdbus_type_boolean
;
49 Lisp_Object QCdbus_type_int16
, QCdbus_type_uint16
;
50 Lisp_Object QCdbus_type_int32
, QCdbus_type_uint32
;
51 Lisp_Object QCdbus_type_int64
, QCdbus_type_uint64
;
52 Lisp_Object QCdbus_type_double
, QCdbus_type_string
;
53 Lisp_Object QCdbus_type_object_path
, QCdbus_type_signature
;
54 Lisp_Object QCdbus_type_array
, QCdbus_type_variant
;
55 Lisp_Object QCdbus_type_struct
, QCdbus_type_dict_entry
;
57 /* Hash table which keeps function definitions. */
58 Lisp_Object Vdbus_registered_functions_table
;
60 /* Whether to debug D-Bus. */
61 Lisp_Object Vdbus_debug
;
64 /* We use "xd_" and "XD_" as prefix for all internal symbols, because
65 we don't want to poison other namespaces with "dbus_". */
67 /* Raise a Lisp error from a D-Bus ERROR. */
68 #define XD_ERROR(error) \
71 strcpy (s, error.message); \
72 dbus_error_free (&error); \
73 /* Remove the trailing newline. */ \
74 if (strchr (s, '\n') != NULL) \
75 s[strlen (s) - 1] = '\0'; \
76 xsignal1 (Qdbus_error, build_string (s)); \
79 /* Macros for debugging. In order to enable them, build with
80 "make MYCPPFLAGS='-DDBUS_DEBUG -Wall'". */
82 #define XD_DEBUG_MESSAGE(...) \
85 sprintf (s, __VA_ARGS__); \
86 printf ("%s: %s\n", __func__, s); \
87 message ("%s: %s", __func__, s); \
89 #define XD_DEBUG_VALID_LISP_OBJECT_P(object) \
91 if (!valid_lisp_object_p (object)) \
93 XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__); \
94 xsignal1 (Qdbus_error, build_string ("Assertion failure")); \
98 #else /* !DBUS_DEBUG */
99 #define XD_DEBUG_MESSAGE(...) \
101 if (!NILP (Vdbus_debug)) \
104 sprintf (s, __VA_ARGS__); \
105 message ("%s: %s", __func__, s); \
108 #define XD_DEBUG_VALID_LISP_OBJECT_P(object)
111 /* Check whether TYPE is a basic DBusType. */
112 #define XD_BASIC_DBUS_TYPE(type) \
113 ((type == DBUS_TYPE_BYTE) \
114 || (type == DBUS_TYPE_BOOLEAN) \
115 || (type == DBUS_TYPE_INT16) \
116 || (type == DBUS_TYPE_UINT16) \
117 || (type == DBUS_TYPE_INT32) \
118 || (type == DBUS_TYPE_UINT32) \
119 || (type == DBUS_TYPE_INT64) \
120 || (type == DBUS_TYPE_UINT64) \
121 || (type == DBUS_TYPE_DOUBLE) \
122 || (type == DBUS_TYPE_STRING) \
123 || (type == DBUS_TYPE_OBJECT_PATH) \
124 || (type == DBUS_TYPE_SIGNATURE))
126 /* Determine the DBusType of a given Lisp symbol. OBJECT must be one
127 of the predefined D-Bus type symbols. */
128 #define XD_SYMBOL_TO_DBUS_TYPE(object) \
129 ((EQ (object, QCdbus_type_byte)) ? DBUS_TYPE_BYTE \
130 : (EQ (object, QCdbus_type_boolean)) ? DBUS_TYPE_BOOLEAN \
131 : (EQ (object, QCdbus_type_int16)) ? DBUS_TYPE_INT16 \
132 : (EQ (object, QCdbus_type_uint16)) ? DBUS_TYPE_UINT16 \
133 : (EQ (object, QCdbus_type_int32)) ? DBUS_TYPE_INT32 \
134 : (EQ (object, QCdbus_type_uint32)) ? DBUS_TYPE_UINT32 \
135 : (EQ (object, QCdbus_type_int64)) ? DBUS_TYPE_INT64 \
136 : (EQ (object, QCdbus_type_uint64)) ? DBUS_TYPE_UINT64 \
137 : (EQ (object, QCdbus_type_double)) ? DBUS_TYPE_DOUBLE \
138 : (EQ (object, QCdbus_type_string)) ? DBUS_TYPE_STRING \
139 : (EQ (object, QCdbus_type_object_path)) ? DBUS_TYPE_OBJECT_PATH \
140 : (EQ (object, QCdbus_type_signature)) ? DBUS_TYPE_SIGNATURE \
141 : (EQ (object, QCdbus_type_array)) ? DBUS_TYPE_ARRAY \
142 : (EQ (object, QCdbus_type_variant)) ? DBUS_TYPE_VARIANT \
143 : (EQ (object, QCdbus_type_struct)) ? DBUS_TYPE_STRUCT \
144 : (EQ (object, QCdbus_type_dict_entry)) ? DBUS_TYPE_DICT_ENTRY \
147 /* Check whether a Lisp symbol is a predefined D-Bus type symbol. */
148 #define XD_DBUS_TYPE_P(object) \
149 (SYMBOLP (object) && ((XD_SYMBOL_TO_DBUS_TYPE (object) != DBUS_TYPE_INVALID)))
151 /* Determine the DBusType of a given Lisp OBJECT. It is used to
152 convert Lisp objects, being arguments of `dbus-call-method' or
153 `dbus-send-signal', into corresponding C values appended as
154 arguments to a D-Bus message. */
155 #define XD_OBJECT_TO_DBUS_TYPE(object) \
156 ((EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN \
157 : (NATNUMP (object)) ? DBUS_TYPE_UINT32 \
158 : (INTEGERP (object)) ? DBUS_TYPE_INT32 \
159 : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \
160 : (STRINGP (object)) ? DBUS_TYPE_STRING \
161 : (XD_DBUS_TYPE_P (object)) ? XD_SYMBOL_TO_DBUS_TYPE (object) \
162 : (CONSP (object)) ? ((XD_DBUS_TYPE_P (CAR_SAFE (object))) \
163 ? XD_SYMBOL_TO_DBUS_TYPE (CAR_SAFE (object)) \
167 /* Return a list pointer which does not have a Lisp symbol as car. */
168 #define XD_NEXT_VALUE(object) \
169 ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object)
171 /* Compute SIGNATURE of OBJECT. It must have a form that it can be
172 used in dbus_message_iter_open_container. DTYPE is the DBusType
173 the object is related to. It is passed as argument, because it
174 cannot be detected in basic type objects, when they are preceded by
175 a type symbol. PARENT_TYPE is the DBusType of a container this
176 signature is embedded, or DBUS_TYPE_INVALID. It is needed for the
177 check that DBUS_TYPE_DICT_ENTRY occurs only as array element. */
179 xd_signature(signature
, dtype
, parent_type
, object
)
181 unsigned int dtype
, parent_type
;
184 unsigned int subtype
;
186 char x
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
193 case DBUS_TYPE_UINT16
:
194 case DBUS_TYPE_UINT32
:
195 case DBUS_TYPE_UINT64
:
196 CHECK_NATNUM (object
);
197 sprintf (signature
, "%c", dtype
);
200 case DBUS_TYPE_BOOLEAN
:
201 if (!EQ (object
, Qt
) && !EQ (object
, Qnil
))
202 wrong_type_argument (intern ("booleanp"), object
);
203 sprintf (signature
, "%c", dtype
);
206 case DBUS_TYPE_INT16
:
207 case DBUS_TYPE_INT32
:
208 case DBUS_TYPE_INT64
:
209 CHECK_NUMBER (object
);
210 sprintf (signature
, "%c", dtype
);
213 case DBUS_TYPE_DOUBLE
:
214 CHECK_FLOAT (object
);
215 sprintf (signature
, "%c", dtype
);
218 case DBUS_TYPE_STRING
:
219 case DBUS_TYPE_OBJECT_PATH
:
220 case DBUS_TYPE_SIGNATURE
:
221 CHECK_STRING (object
);
222 sprintf (signature
, "%c", dtype
);
225 case DBUS_TYPE_ARRAY
:
226 /* Check that all list elements have the same D-Bus type. For
227 complex element types, we just check the container type, not
228 the whole element's signature. */
231 /* Type symbol is optional. */
232 if (EQ (QCdbus_type_array
, CAR_SAFE (elt
)))
233 elt
= XD_NEXT_VALUE (elt
);
235 /* If the array is empty, DBUS_TYPE_STRING is the default
239 subtype
= DBUS_TYPE_STRING
;
240 strcpy (x
, DBUS_TYPE_STRING_AS_STRING
);
244 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
245 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
248 /* If the element type is DBUS_TYPE_SIGNATURE, and this is the
249 only element, the value of this element is used as he array's
250 element signature. */
251 if ((subtype
== DBUS_TYPE_SIGNATURE
)
252 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt
)))
253 && NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
254 strcpy (x
, SDATA (CAR_SAFE (XD_NEXT_VALUE (elt
))));
258 if (subtype
!= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
)))
259 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (elt
));
260 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
263 sprintf (signature
, "%c%s", dtype
, x
);
266 case DBUS_TYPE_VARIANT
:
267 /* Check that there is exactly one list element. */
270 elt
= XD_NEXT_VALUE (elt
);
271 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
272 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
274 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
275 wrong_type_argument (intern ("D-Bus"),
276 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt
))));
278 sprintf (signature
, "%c", dtype
);
281 case DBUS_TYPE_STRUCT
:
282 /* A struct list might contain any number of elements with
283 different types. No further check needed. */
286 elt
= XD_NEXT_VALUE (elt
);
288 /* Compose the signature from the elements. It is enclosed by
290 sprintf (signature
, "%c", DBUS_STRUCT_BEGIN_CHAR
);
293 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
294 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
295 strcat (signature
, x
);
296 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
298 sprintf (signature
, "%s%c", signature
, DBUS_STRUCT_END_CHAR
);
301 case DBUS_TYPE_DICT_ENTRY
:
302 /* Check that there are exactly two list elements, and the first
303 one is of basic type. The dictionary entry itself must be an
304 element of an array. */
307 /* Check the parent object type. */
308 if (parent_type
!= DBUS_TYPE_ARRAY
)
309 wrong_type_argument (intern ("D-Bus"), object
);
311 /* Compose the signature from the elements. It is enclosed by
313 sprintf (signature
, "%c", DBUS_DICT_ENTRY_BEGIN_CHAR
);
316 elt
= XD_NEXT_VALUE (elt
);
317 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
318 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
319 strcat (signature
, x
);
321 if (!XD_BASIC_DBUS_TYPE (subtype
))
322 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt
)));
324 /* Second element. */
325 elt
= CDR_SAFE (XD_NEXT_VALUE (elt
));
326 subtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt
));
327 xd_signature (x
, subtype
, dtype
, CAR_SAFE (XD_NEXT_VALUE (elt
)));
328 strcat (signature
, x
);
330 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt
))))
331 wrong_type_argument (intern ("D-Bus"),
332 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt
))));
334 /* Closing signature. */
335 sprintf (signature
, "%s%c", signature
, DBUS_DICT_ENTRY_END_CHAR
);
339 wrong_type_argument (intern ("D-Bus"), object
);
342 XD_DEBUG_MESSAGE ("%s", signature
);
345 /* Append C value, extracted from Lisp OBJECT, to iteration ITER.
346 DTYPE must be a valid DBusType. It is used to convert Lisp
347 objects, being arguments of `dbus-call-method' or
348 `dbus-send-signal', into corresponding C values appended as
349 arguments to a D-Bus message. */
351 xd_append_arg (dtype
, object
, iter
)
354 DBusMessageIter
*iter
;
356 char signature
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
357 DBusMessageIter subiter
;
359 if (XD_BASIC_DBUS_TYPE (dtype
))
364 unsigned char val
= XUINT (object
) & 0xFF;
365 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
366 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
367 xsignal2 (Qdbus_error
,
368 build_string ("Unable to append argument"), object
);
372 case DBUS_TYPE_BOOLEAN
:
374 dbus_bool_t val
= (NILP (object
)) ? FALSE
: TRUE
;
375 XD_DEBUG_MESSAGE ("%c %s", dtype
, (val
== FALSE
) ? "false" : "true");
376 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
377 xsignal2 (Qdbus_error
,
378 build_string ("Unable to append argument"), object
);
382 case DBUS_TYPE_INT16
:
384 dbus_int16_t val
= XINT (object
);
385 XD_DEBUG_MESSAGE ("%c %d", dtype
, (int) val
);
386 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
387 xsignal2 (Qdbus_error
,
388 build_string ("Unable to append argument"), object
);
392 case DBUS_TYPE_UINT16
:
394 dbus_uint16_t val
= XUINT (object
);
395 XD_DEBUG_MESSAGE ("%c %u", dtype
, (unsigned int) val
);
396 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
397 xsignal2 (Qdbus_error
,
398 build_string ("Unable to append argument"), object
);
402 case DBUS_TYPE_INT32
:
404 dbus_int32_t val
= XINT (object
);
405 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
406 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
407 xsignal2 (Qdbus_error
,
408 build_string ("Unable to append argument"), object
);
412 case DBUS_TYPE_UINT32
:
414 dbus_uint32_t val
= XUINT (object
);
415 XD_DEBUG_MESSAGE ("%c %u", dtype
, val
);
416 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
417 xsignal2 (Qdbus_error
,
418 build_string ("Unable to append argument"), object
);
422 case DBUS_TYPE_INT64
:
424 dbus_int64_t val
= XINT (object
);
425 XD_DEBUG_MESSAGE ("%c %d", dtype
, (int) val
);
426 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
427 xsignal2 (Qdbus_error
,
428 build_string ("Unable to append argument"), object
);
432 case DBUS_TYPE_UINT64
:
434 dbus_uint64_t val
= XUINT (object
);
435 XD_DEBUG_MESSAGE ("%c %u", dtype
, (unsigned int) val
);
436 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
437 xsignal2 (Qdbus_error
,
438 build_string ("Unable to append argument"), object
);
442 case DBUS_TYPE_DOUBLE
:
443 XD_DEBUG_MESSAGE ("%c %f", dtype
, XFLOAT_DATA (object
));
444 if (!dbus_message_iter_append_basic (iter
, dtype
,
445 &XFLOAT_DATA (object
)))
446 xsignal2 (Qdbus_error
,
447 build_string ("Unable to append argument"), object
);
450 case DBUS_TYPE_STRING
:
451 case DBUS_TYPE_OBJECT_PATH
:
452 case DBUS_TYPE_SIGNATURE
:
454 char *val
= SDATA (object
);
455 XD_DEBUG_MESSAGE ("%c %s", dtype
, val
);
456 if (!dbus_message_iter_append_basic (iter
, dtype
, &val
))
457 xsignal2 (Qdbus_error
,
458 build_string ("Unable to append argument"), object
);
463 else /* Compound types. */
466 /* All compound types except array have a type symbol. For
467 array, it is optional. Skip it. */
468 if (!XD_BASIC_DBUS_TYPE (XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
))))
469 object
= XD_NEXT_VALUE (object
);
471 /* Open new subiteration. */
474 case DBUS_TYPE_ARRAY
:
475 /* An array has only elements of the same type. So it is
476 sufficient to check the first element's signature
480 /* If the array is empty, DBUS_TYPE_STRING is the default
482 strcpy (signature
, DBUS_TYPE_STRING_AS_STRING
);
485 /* If the element type is DBUS_TYPE_SIGNATURE, and this is
486 the only element, the value of this element is used as
487 the array's element signature. */
488 if ((XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
))
489 == DBUS_TYPE_SIGNATURE
)
490 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object
)))
491 && NILP (CDR_SAFE (XD_NEXT_VALUE (object
))))
493 strcpy (signature
, SDATA (CAR_SAFE (XD_NEXT_VALUE (object
))));
494 object
= CDR_SAFE (XD_NEXT_VALUE (object
));
498 xd_signature (signature
,
499 XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
)),
500 dtype
, CAR_SAFE (XD_NEXT_VALUE (object
)));
502 XD_DEBUG_MESSAGE ("%c %s %s", dtype
, signature
,
503 SDATA (format2 ("%s", object
, Qnil
)));
504 if (!dbus_message_iter_open_container (iter
, dtype
,
505 signature
, &subiter
))
506 xsignal3 (Qdbus_error
,
507 build_string ("Cannot open container"),
508 make_number (dtype
), build_string (signature
));
511 case DBUS_TYPE_VARIANT
:
512 /* A variant has just one element. */
513 xd_signature (signature
, XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
)),
514 dtype
, CAR_SAFE (XD_NEXT_VALUE (object
)));
516 XD_DEBUG_MESSAGE ("%c %s %s", dtype
, signature
,
517 SDATA (format2 ("%s", object
, Qnil
)));
518 if (!dbus_message_iter_open_container (iter
, dtype
,
519 signature
, &subiter
))
520 xsignal3 (Qdbus_error
,
521 build_string ("Cannot open container"),
522 make_number (dtype
), build_string (signature
));
525 case DBUS_TYPE_STRUCT
:
526 case DBUS_TYPE_DICT_ENTRY
:
527 /* These containers do not require a signature. */
528 XD_DEBUG_MESSAGE ("%c %s", dtype
,
529 SDATA (format2 ("%s", object
, Qnil
)));
530 if (!dbus_message_iter_open_container (iter
, dtype
, NULL
, &subiter
))
531 xsignal2 (Qdbus_error
,
532 build_string ("Cannot open container"),
533 make_number (dtype
));
537 /* Loop over list elements. */
538 while (!NILP (object
))
540 dtype
= XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object
));
541 object
= XD_NEXT_VALUE (object
);
543 xd_append_arg (dtype
, CAR_SAFE (object
), &subiter
);
545 object
= CDR_SAFE (object
);
548 /* Close the subiteration. */
549 if (!dbus_message_iter_close_container (iter
, &subiter
))
550 xsignal2 (Qdbus_error
,
551 build_string ("Cannot close container"),
552 make_number (dtype
));
556 /* Retrieve C value from a DBusMessageIter structure ITER, and return
557 a converted Lisp object. The type DTYPE of the argument of the
558 D-Bus message must be a valid DBusType. Compound D-Bus types
559 result always in a Lisp list. */
561 xd_retrieve_arg (dtype
, iter
)
563 DBusMessageIter
*iter
;
571 dbus_message_iter_get_basic (iter
, &val
);
573 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
574 return make_number (val
);
577 case DBUS_TYPE_BOOLEAN
:
580 dbus_message_iter_get_basic (iter
, &val
);
581 XD_DEBUG_MESSAGE ("%c %s", dtype
, (val
== FALSE
) ? "false" : "true");
582 return (val
== FALSE
) ? Qnil
: Qt
;
585 case DBUS_TYPE_INT16
:
586 case DBUS_TYPE_UINT16
:
589 dbus_message_iter_get_basic (iter
, &val
);
590 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
591 return make_number (val
);
594 case DBUS_TYPE_INT32
:
595 case DBUS_TYPE_UINT32
:
597 /* Assignment to EMACS_INT stops GCC whining about limited
598 range of data type. */
601 dbus_message_iter_get_basic (iter
, &val
);
602 XD_DEBUG_MESSAGE ("%c %d", dtype
, val
);
604 return make_fixnum_or_float (val1
);
607 case DBUS_TYPE_INT64
:
608 case DBUS_TYPE_UINT64
:
611 dbus_message_iter_get_basic (iter
, &val
);
612 XD_DEBUG_MESSAGE ("%c %d", dtype
, (int) val
);
613 return make_fixnum_or_float (val
);
616 case DBUS_TYPE_DOUBLE
:
619 dbus_message_iter_get_basic (iter
, &val
);
620 XD_DEBUG_MESSAGE ("%c %f", dtype
, val
);
621 return make_float (val
);
624 case DBUS_TYPE_STRING
:
625 case DBUS_TYPE_OBJECT_PATH
:
626 case DBUS_TYPE_SIGNATURE
:
629 dbus_message_iter_get_basic (iter
, &val
);
630 XD_DEBUG_MESSAGE ("%c %s", dtype
, val
);
631 return build_string (val
);
634 case DBUS_TYPE_ARRAY
:
635 case DBUS_TYPE_VARIANT
:
636 case DBUS_TYPE_STRUCT
:
637 case DBUS_TYPE_DICT_ENTRY
:
643 DBusMessageIter subiter
;
645 dbus_message_iter_recurse (iter
, &subiter
);
646 while ((subtype
= dbus_message_iter_get_arg_type (&subiter
))
647 != DBUS_TYPE_INVALID
)
649 result
= Fcons (xd_retrieve_arg (subtype
, &subiter
), result
);
650 dbus_message_iter_next (&subiter
);
652 XD_DEBUG_MESSAGE ("%c %s", dtype
, SDATA (format2 ("%s", result
, Qnil
)));
653 RETURN_UNGCPRO (Fnreverse (result
));
657 XD_DEBUG_MESSAGE ("DBusType '%c' not supported", dtype
);
662 /* Initialize D-Bus connection. BUS is a Lisp symbol, either :system
663 or :session. It tells which D-Bus to be initialized. */
668 DBusConnection
*connection
;
671 /* Parameter check. */
673 if (!((EQ (bus
, QCdbus_system_bus
)) || (EQ (bus
, QCdbus_session_bus
))))
674 xsignal2 (Qdbus_error
, build_string ("Wrong bus name"), bus
);
676 /* Open a connection to the bus. */
677 dbus_error_init (&derror
);
679 if (EQ (bus
, QCdbus_system_bus
))
680 connection
= dbus_bus_get (DBUS_BUS_SYSTEM
, &derror
);
682 connection
= dbus_bus_get (DBUS_BUS_SESSION
, &derror
);
684 if (dbus_error_is_set (&derror
))
687 if (connection
== NULL
)
688 xsignal2 (Qdbus_error
, build_string ("No connection"), bus
);
690 /* Return the result. */
694 DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name
, Sdbus_get_unique_name
,
696 doc
: /* Return the unique name of Emacs registered at D-Bus BUS. */)
700 DBusConnection
*connection
;
701 char name
[DBUS_MAXIMUM_NAME_LENGTH
];
703 /* Check parameters. */
706 /* Open a connection to the bus. */
707 connection
= xd_initialize (bus
);
709 /* Request the name. */
710 strcpy (name
, dbus_bus_get_unique_name (connection
));
712 xsignal1 (Qdbus_error
, build_string ("No unique name available"));
715 return build_string (name
);
718 DEFUN ("dbus-call-method", Fdbus_call_method
, Sdbus_call_method
, 5, MANY
, 0,
719 doc
: /* Call METHOD on the D-Bus BUS.
721 BUS is either the symbol `:system' or the symbol `:session'.
723 SERVICE is the D-Bus service name to be used. PATH is the D-Bus
724 object path SERVICE is registered at. INTERFACE is an interface
725 offered by SERVICE. It must provide METHOD.
727 All other arguments ARGS are passed to METHOD as arguments. They are
728 converted into D-Bus types via the following rules:
730 t and nil => DBUS_TYPE_BOOLEAN
731 number => DBUS_TYPE_UINT32
732 integer => DBUS_TYPE_INT32
733 float => DBUS_TYPE_DOUBLE
734 string => DBUS_TYPE_STRING
735 list => DBUS_TYPE_ARRAY
737 All arguments can be preceded by a type symbol. For details about
738 type symbols, see Info node `(dbus)Type Conversion'.
740 `dbus-call-method' returns the resulting values of METHOD as a list of
741 Lisp objects. The type conversion happens the other direction as for
742 input arguments. It follows the mapping rules:
744 DBUS_TYPE_BOOLEAN => t or nil
745 DBUS_TYPE_BYTE => number
746 DBUS_TYPE_UINT16 => number
747 DBUS_TYPE_INT16 => integer
748 DBUS_TYPE_UINT32 => number or float
749 DBUS_TYPE_INT32 => integer or float
750 DBUS_TYPE_UINT64 => number or float
751 DBUS_TYPE_INT64 => integer or float
752 DBUS_TYPE_DOUBLE => float
753 DBUS_TYPE_STRING => string
754 DBUS_TYPE_OBJECT_PATH => string
755 DBUS_TYPE_SIGNATURE => string
756 DBUS_TYPE_ARRAY => list
757 DBUS_TYPE_VARIANT => list
758 DBUS_TYPE_STRUCT => list
759 DBUS_TYPE_DICT_ENTRY => list
764 :session "org.gnome.seahorse" "/org/gnome/seahorse/keys/openpgp"
765 "org.gnome.seahorse.Keys" "GetKeyField"
766 "openpgp:657984B8C7A966DD" "simple-name")
768 => (t ("Philip R. Zimmermann"))
770 If the result of the METHOD call is just one value, the converted Lisp
771 object is returned instead of a list containing this single Lisp object.
774 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer"
775 "org.freedesktop.Hal.Device" "GetPropertyString"
776 "system.kernel.machine")
780 usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &rest ARGS) */)
783 register Lisp_Object
*args
;
785 Lisp_Object bus
, service
, path
, interface
, method
;
787 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
788 DBusConnection
*connection
;
789 DBusMessage
*dmessage
;
791 DBusMessageIter iter
;
795 char signature
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
797 /* Check parameters. */
805 CHECK_STRING (service
);
807 CHECK_STRING (interface
);
808 CHECK_STRING (method
);
809 GCPRO5 (bus
, service
, path
, interface
, method
);
811 XD_DEBUG_MESSAGE ("%s %s %s %s",
817 /* Open a connection to the bus. */
818 connection
= xd_initialize (bus
);
820 /* Create the message. */
821 dmessage
= dbus_message_new_method_call (SDATA (service
),
825 if (dmessage
== NULL
)
828 xsignal1 (Qdbus_error
, build_string ("Unable to create a new message"));
833 /* Initialize parameter list of message. */
834 dbus_message_iter_init_append (dmessage
, &iter
);
836 /* Append parameters to the message. */
837 for (i
= 5; i
< nargs
; ++i
)
839 dtype
= XD_OBJECT_TO_DBUS_TYPE (args
[i
]);
840 if (XD_DBUS_TYPE_P (args
[i
]))
842 XD_DEBUG_VALID_LISP_OBJECT_P (args
[i
]);
843 XD_DEBUG_VALID_LISP_OBJECT_P (args
[i
+1]);
844 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i
-4,
845 SDATA (format2 ("%s", args
[i
], Qnil
)),
846 SDATA (format2 ("%s", args
[i
+1], Qnil
)));
851 XD_DEBUG_VALID_LISP_OBJECT_P (args
[i
]);
852 XD_DEBUG_MESSAGE ("Parameter%d %s", i
-4,
853 SDATA (format2 ("%s", args
[i
], Qnil
)));
856 /* Check for valid signature. We use DBUS_TYPE_INVALID as
857 indication that there is no parent type. */
858 xd_signature (signature
, dtype
, DBUS_TYPE_INVALID
, args
[i
]);
860 xd_append_arg (dtype
, args
[i
], &iter
);
863 /* Send the message. */
864 dbus_error_init (&derror
);
865 reply
= dbus_connection_send_with_reply_and_block (connection
,
870 if (dbus_error_is_set (&derror
))
874 xsignal1 (Qdbus_error
, build_string ("No reply"));
876 XD_DEBUG_MESSAGE ("Message sent");
878 /* Collect the results. */
882 if (dbus_message_iter_init (reply
, &iter
))
884 /* Loop over the parameters of the D-Bus reply message. Construct a
885 Lisp list, which is returned by `dbus-call-method'. */
886 while ((dtype
= dbus_message_iter_get_arg_type (&iter
))
887 != DBUS_TYPE_INVALID
)
889 result
= Fcons (xd_retrieve_arg (dtype
, &iter
), result
);
890 dbus_message_iter_next (&iter
);
895 /* No arguments: just return nil. */
899 dbus_message_unref (dmessage
);
900 dbus_message_unref (reply
);
902 /* Return the result. If there is only one single Lisp object,
903 return it as-it-is, otherwise return the reversed list. */
904 if (XUINT (Flength (result
)) == 1)
905 RETURN_UNGCPRO (CAR_SAFE (result
));
907 RETURN_UNGCPRO (Fnreverse (result
));
910 DEFUN ("dbus-method-return-internal", Fdbus_method_return_internal
,
911 Sdbus_method_return_internal
,
913 doc
: /* Return for message SERIAL on the D-Bus BUS.
914 This is an internal function, it shall not be used outside dbus.el.
916 usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */)
919 register Lisp_Object
*args
;
921 Lisp_Object bus
, serial
, service
;
922 struct gcpro gcpro1
, gcpro2
, gcpro3
;
923 DBusConnection
*connection
;
924 DBusMessage
*dmessage
;
925 DBusMessageIter iter
;
928 char signature
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
930 /* Check parameters. */
936 CHECK_NUMBER (serial
);
937 CHECK_STRING (service
);
938 GCPRO3 (bus
, serial
, service
);
940 XD_DEBUG_MESSAGE ("%d %s ", XUINT (serial
), SDATA (service
));
942 /* Open a connection to the bus. */
943 connection
= xd_initialize (bus
);
945 /* Create the message. */
946 dmessage
= dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN
);
947 if ((dmessage
== NULL
)
948 || (!dbus_message_set_reply_serial (dmessage
, XUINT (serial
)))
949 || (!dbus_message_set_destination (dmessage
, SDATA (service
))))
952 xsignal1 (Qdbus_error
,
953 build_string ("Unable to create a return message"));
958 /* Initialize parameter list of message. */
959 dbus_message_iter_init_append (dmessage
, &iter
);
961 /* Append parameters to the message. */
962 for (i
= 3; i
< nargs
; ++i
)
964 dtype
= XD_OBJECT_TO_DBUS_TYPE (args
[i
]);
965 if (XD_DBUS_TYPE_P (args
[i
]))
967 XD_DEBUG_VALID_LISP_OBJECT_P (args
[i
]);
968 XD_DEBUG_VALID_LISP_OBJECT_P (args
[i
+1]);
969 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i
-2,
970 SDATA (format2 ("%s", args
[i
], Qnil
)),
971 SDATA (format2 ("%s", args
[i
+1], Qnil
)));
976 XD_DEBUG_VALID_LISP_OBJECT_P (args
[i
]);
977 XD_DEBUG_MESSAGE ("Parameter%d %s", i
-2,
978 SDATA (format2 ("%s", args
[i
], Qnil
)));
981 /* Check for valid signature. We use DBUS_TYPE_INVALID as
982 indication that there is no parent type. */
983 xd_signature (signature
, dtype
, DBUS_TYPE_INVALID
, args
[i
]);
985 xd_append_arg (dtype
, args
[i
], &iter
);
988 /* Send the message. The message is just added to the outgoing
990 if (!dbus_connection_send (connection
, dmessage
, NULL
))
991 xsignal1 (Qdbus_error
, build_string ("Cannot send message"));
993 /* Flush connection to ensure the message is handled. */
994 dbus_connection_flush (connection
);
996 XD_DEBUG_MESSAGE ("Message sent");
999 dbus_message_unref (dmessage
);
1005 DEFUN ("dbus-send-signal", Fdbus_send_signal
, Sdbus_send_signal
, 5, MANY
, 0,
1006 doc
: /* Send signal SIGNAL on the D-Bus BUS.
1008 BUS is either the symbol `:system' or the symbol `:session'.
1010 SERVICE is the D-Bus service name SIGNAL is sent from. PATH is the
1011 D-Bus object path SERVICE is registered at. INTERFACE is an interface
1012 offered by SERVICE. It must provide signal SIGNAL.
1014 All other arguments ARGS are passed to SIGNAL as arguments. They are
1015 converted into D-Bus types via the following rules:
1017 t and nil => DBUS_TYPE_BOOLEAN
1018 number => DBUS_TYPE_UINT32
1019 integer => DBUS_TYPE_INT32
1020 float => DBUS_TYPE_DOUBLE
1021 string => DBUS_TYPE_STRING
1022 list => DBUS_TYPE_ARRAY
1024 All arguments can be preceded by a type symbol. For details about
1025 type symbols, see Info node `(dbus)Type Conversion'.
1030 :session "org.gnu.Emacs" "/org/gnu/Emacs"
1031 "org.gnu.Emacs.FileManager" "FileModified" "/home/albinus/.emacs")
1033 usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
1036 register Lisp_Object
*args
;
1038 Lisp_Object bus
, service
, path
, interface
, signal
;
1039 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
1040 DBusConnection
*connection
;
1041 DBusMessage
*dmessage
;
1042 DBusMessageIter iter
;
1045 char signature
[DBUS_MAXIMUM_SIGNATURE_LENGTH
];
1047 /* Check parameters. */
1051 interface
= args
[3];
1055 CHECK_STRING (service
);
1056 CHECK_STRING (path
);
1057 CHECK_STRING (interface
);
1058 CHECK_STRING (signal
);
1059 GCPRO5 (bus
, service
, path
, interface
, signal
);
1061 XD_DEBUG_MESSAGE ("%s %s %s %s",
1067 /* Open a connection to the bus. */
1068 connection
= xd_initialize (bus
);
1070 /* Create the message. */
1071 dmessage
= dbus_message_new_signal (SDATA (path
),
1074 if (dmessage
== NULL
)
1077 xsignal1 (Qdbus_error
, build_string ("Unable to create a new message"));
1082 /* Initialize parameter list of message. */
1083 dbus_message_iter_init_append (dmessage
, &iter
);
1085 /* Append parameters to the message. */
1086 for (i
= 5; i
< nargs
; ++i
)
1088 dtype
= XD_OBJECT_TO_DBUS_TYPE (args
[i
]);
1089 if (XD_DBUS_TYPE_P (args
[i
]))
1091 XD_DEBUG_VALID_LISP_OBJECT_P (args
[i
]);
1092 XD_DEBUG_VALID_LISP_OBJECT_P (args
[i
+1]);
1093 XD_DEBUG_MESSAGE ("Parameter%d %s %s", i
-4,
1094 SDATA (format2 ("%s", args
[i
], Qnil
)),
1095 SDATA (format2 ("%s", args
[i
+1], Qnil
)));
1100 XD_DEBUG_VALID_LISP_OBJECT_P (args
[i
]);
1101 XD_DEBUG_MESSAGE ("Parameter%d %s", i
-4,
1102 SDATA (format2 ("%s", args
[i
], Qnil
)));
1105 /* Check for valid signature. We use DBUS_TYPE_INVALID as
1106 indication that there is no parent type. */
1107 xd_signature (signature
, dtype
, DBUS_TYPE_INVALID
, args
[i
]);
1109 xd_append_arg (dtype
, args
[i
], &iter
);
1112 /* Send the message. The message is just added to the outgoing
1114 if (!dbus_connection_send (connection
, dmessage
, NULL
))
1115 xsignal1 (Qdbus_error
, build_string ("Cannot send message"));
1117 /* Flush connection to ensure the message is handled. */
1118 dbus_connection_flush (connection
);
1120 XD_DEBUG_MESSAGE ("Signal sent");
1123 dbus_message_unref (dmessage
);
1129 /* Read queued incoming message of the D-Bus BUS. BUS is a Lisp
1130 symbol, either :system or :session. */
1132 xd_read_message (bus
)
1135 Lisp_Object args
, key
, value
;
1136 struct gcpro gcpro1
;
1137 struct input_event event
;
1138 DBusConnection
*connection
;
1139 DBusMessage
*dmessage
;
1140 DBusMessageIter iter
;
1143 char uname
[DBUS_MAXIMUM_NAME_LENGTH
];
1144 char path
[DBUS_MAXIMUM_MATCH_RULE_LENGTH
]; /* Unlimited in D-Bus spec. */
1145 char interface
[DBUS_MAXIMUM_NAME_LENGTH
];
1146 char member
[DBUS_MAXIMUM_NAME_LENGTH
];
1148 /* Open a connection to the bus. */
1149 connection
= xd_initialize (bus
);
1151 /* Non blocking read of the next available message. */
1152 dbus_connection_read_write (connection
, 0);
1153 dmessage
= dbus_connection_pop_message (connection
);
1155 /* Return if there is no queued message. */
1156 if (dmessage
== NULL
)
1159 /* Collect the parameters. */
1163 /* Loop over the resulting parameters. Construct a list. */
1164 if (dbus_message_iter_init (dmessage
, &iter
))
1166 while ((dtype
= dbus_message_iter_get_arg_type (&iter
))
1167 != DBUS_TYPE_INVALID
)
1169 args
= Fcons (xd_retrieve_arg (dtype
, &iter
), args
);
1170 dbus_message_iter_next (&iter
);
1172 /* The arguments are stored in reverse order. Reorder them. */
1173 args
= Fnreverse (args
);
1176 /* Read message type, unique name, object path, interface and member
1177 from the message. */
1178 mtype
= dbus_message_get_type (dmessage
);
1179 strcpy (uname
, dbus_message_get_sender (dmessage
));
1180 strcpy (path
, dbus_message_get_path (dmessage
));
1181 strcpy (interface
, dbus_message_get_interface (dmessage
));
1182 strcpy (member
, dbus_message_get_member (dmessage
));
1184 XD_DEBUG_MESSAGE ("Event received: %d %s %s %s %s %s",
1185 mtype
, uname
, path
, interface
, member
,
1186 SDATA (format2 ("%s", args
, Qnil
)));
1188 /* Search for a registered function of the message. */
1189 key
= list3 (bus
, build_string (interface
), build_string (member
));
1190 value
= Fgethash (key
, Vdbus_registered_functions_table
, Qnil
);
1192 /* Loop over the registered functions. Construct an event. */
1193 while (!NILP (value
))
1195 key
= CAR_SAFE (value
);
1196 /* key has the structure (UNAME SERVICE PATH HANDLER). */
1197 if (((uname
== NULL
)
1198 || (NILP (CAR_SAFE (key
)))
1199 || (strcmp (uname
, SDATA (CAR_SAFE (key
))) == 0))
1201 || (NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))
1202 || (strcmp (path
, SDATA (CAR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))
1204 && (!NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key
)))))))
1207 event
.kind
= DBUS_EVENT
;
1208 event
.frame_or_window
= Qnil
;
1209 event
.arg
= Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key
)))),
1212 /* Add uname, path, interface and member to the event. */
1213 event
.arg
= Fcons ((member
== NULL
? Qnil
: build_string (member
)),
1215 event
.arg
= Fcons ((interface
== NULL
1216 ? Qnil
: build_string (interface
)),
1218 event
.arg
= Fcons ((path
== NULL
? Qnil
: build_string (path
)),
1220 event
.arg
= Fcons ((uname
== NULL
? Qnil
: build_string (uname
)),
1223 /* Add the message serial if needed, or nil. */
1224 event
.arg
= Fcons ((mtype
== DBUS_MESSAGE_TYPE_METHOD_CALL
1225 ? make_number (dbus_message_get_serial (dmessage
))
1229 /* Add the bus symbol to the event. */
1230 event
.arg
= Fcons (bus
, event
.arg
);
1232 /* Store it into the input event queue. */
1233 kbd_buffer_store_event (&event
);
1235 value
= CDR_SAFE (value
);
1239 dbus_message_unref (dmessage
);
1240 RETURN_UNGCPRO (Qnil
);
1243 /* Read queued incoming messages from the system and session buses. */
1245 xd_read_queued_messages ()
1248 /* Vdbus_registered_functions_table will be initialized as hash
1249 table in dbus.el. When this package isn't loaded yet, it doesn't
1250 make sense to handle D-Bus messages. Furthermore, we ignore all
1251 Lisp errors during the call. */
1252 if (HASH_TABLE_P (Vdbus_registered_functions_table
))
1254 internal_condition_case_1 (xd_read_message
, QCdbus_system_bus
,
1256 internal_condition_case_1 (xd_read_message
, QCdbus_session_bus
,
1261 DEFUN ("dbus-register-signal", Fdbus_register_signal
, Sdbus_register_signal
,
1263 doc
: /* Register for signal SIGNAL on the D-Bus BUS.
1265 BUS is either the symbol `:system' or the symbol `:session'.
1267 SERVICE is the D-Bus service name used by the sending D-Bus object.
1268 It can be either a known name or the unique name of the D-Bus object
1269 sending the signal. When SERVICE is nil, related signals from all
1270 D-Bus objects shall be accepted.
1272 PATH is the D-Bus object path SERVICE is registered. It can also be
1273 nil if the path name of incoming signals shall not be checked.
1275 INTERFACE is an interface offered by SERVICE. It must provide SIGNAL.
1276 HANDLER is a Lisp function to be called when the signal is received.
1277 It must accept as arguments the values SIGNAL is sending. INTERFACE,
1278 SIGNAL and HANDLER must not be nil. Example:
1280 \(defun my-signal-handler (device)
1281 (message "Device %s added" device))
1283 \(dbus-register-signal
1284 :system "org.freedesktop.Hal" "/org/freedesktop/Hal/Manager"
1285 "org.freedesktop.Hal.Manager" "DeviceAdded" 'my-signal-handler)
1287 => ((:system "org.freedesktop.Hal.Manager" "DeviceAdded")
1288 ("org.freedesktop.Hal" "/org/freedesktop/Hal/Manager" my-signal-handler))
1290 `dbus-register-signal' returns an object, which can be used in
1291 `dbus-unregister-object' for removing the registration. */)
1292 (bus
, service
, path
, interface
, signal
, handler
)
1293 Lisp_Object bus
, service
, path
, interface
, signal
, handler
;
1295 Lisp_Object uname
, key
, key1
, value
;
1296 DBusConnection
*connection
;
1297 char rule
[DBUS_MAXIMUM_MATCH_RULE_LENGTH
];
1300 /* Check parameters. */
1302 if (!NILP (service
)) CHECK_STRING (service
);
1303 if (!NILP (path
)) CHECK_STRING (path
);
1304 CHECK_STRING (interface
);
1305 CHECK_STRING (signal
);
1306 if (!FUNCTIONP (handler
))
1307 wrong_type_argument (intern ("functionp"), handler
);
1309 /* Retrieve unique name of service. If service is a known name, we
1310 will register for the corresponding unique name, if any. Signals
1311 are sent always with the unique name as sender. Note: the unique
1312 name of "org.freedesktop.DBus" is that string itself. */
1313 if ((STRINGP (service
))
1314 && (SBYTES (service
) > 0)
1315 && (strcmp (SDATA (service
), DBUS_SERVICE_DBUS
) != 0)
1316 && (strncmp (SDATA (service
), ":", 1) != 0))
1318 uname
= call2 (intern ("dbus-get-name-owner"), bus
, service
);
1319 /* When there is no unique name, we mark it with an empty
1322 uname
= build_string ("");
1327 /* Create a matching rule if the unique name exists (when no
1329 if (NILP (uname
) || (SBYTES (uname
) > 0))
1331 /* Open a connection to the bus. */
1332 connection
= xd_initialize (bus
);
1334 /* Create a rule to receive related signals. */
1336 "type='signal',interface='%s',member='%s'",
1340 /* Add unique name and path to the rule if they are non-nil. */
1342 sprintf (rule
, "%s,sender='%s'", rule
, SDATA (uname
));
1345 sprintf (rule
, "%s,path='%s'", rule
, SDATA (path
));
1347 /* Add the rule to the bus. */
1348 dbus_error_init (&derror
);
1349 dbus_bus_add_match (connection
, rule
, &derror
);
1350 if (dbus_error_is_set (&derror
))
1353 XD_DEBUG_MESSAGE ("Matching rule \"%s\" created", rule
);
1356 /* Create a hash table entry. */
1357 key
= list3 (bus
, interface
, signal
);
1358 key1
= list4 (uname
, service
, path
, handler
);
1359 value
= Fgethash (key
, Vdbus_registered_functions_table
, Qnil
);
1361 if (NILP (Fmember (key1
, value
)))
1362 Fputhash (key
, Fcons (key1
, value
), Vdbus_registered_functions_table
);
1364 /* Return object. */
1365 return list2 (key
, list3 (service
, path
, handler
));
1368 DEFUN ("dbus-register-method", Fdbus_register_method
, Sdbus_register_method
,
1370 doc
: /* Register for method METHOD on the D-Bus BUS.
1372 BUS is either the symbol `:system' or the symbol `:session'.
1374 SERVICE is the D-Bus service name of the D-Bus object METHOD is
1375 registered for. It must be a known name.
1377 PATH is the D-Bus object path SERVICE is registered. INTERFACE is the
1378 interface offered by SERVICE. It must provide METHOD. HANDLER is a
1379 Lisp function to be called when a method call is received. It must
1380 accept the input arguments of METHOD. The return value of HANDLER is
1381 used for composing the returning D-Bus message. */)
1382 (bus
, service
, path
, interface
, method
, handler
)
1383 Lisp_Object bus
, service
, path
, interface
, method
, handler
;
1385 Lisp_Object key
, key1
, value
;
1386 DBusConnection
*connection
;
1390 /* Check parameters. */
1392 CHECK_STRING (service
);
1393 CHECK_STRING (path
);
1394 CHECK_STRING (interface
);
1395 CHECK_STRING (method
);
1396 if (!FUNCTIONP (handler
))
1397 wrong_type_argument (intern ("functionp"), handler
);
1398 /* TODO: We must check for a valid service name, otherwise there is
1399 a segmentation fault. */
1401 /* Open a connection to the bus. */
1402 connection
= xd_initialize (bus
);
1404 /* Request the known name from the bus. We can ignore the result,
1405 it is set to -1 if there is an error - kind of redundancy. */
1406 dbus_error_init (&derror
);
1407 result
= dbus_bus_request_name (connection
, SDATA (service
), 0, &derror
);
1408 if (dbus_error_is_set (&derror
))
1411 /* Create a hash table entry. */
1412 key
= list3 (bus
, interface
, method
);
1413 key1
= list4 (Qnil
, service
, path
, handler
);
1414 value
= Fgethash (key
, Vdbus_registered_functions_table
, Qnil
);
1416 /* We use nil for the unique name, because the method might be
1417 called from everybody. */
1418 if (NILP (Fmember (key1
, value
)))
1419 Fputhash (key
, Fcons (key1
, value
), Vdbus_registered_functions_table
);
1421 /* Return object. */
1422 return list2 (key
, list3 (service
, path
, handler
));
1430 Qdbus_get_unique_name
= intern ("dbus-get-unique-name");
1431 staticpro (&Qdbus_get_unique_name
);
1432 defsubr (&Sdbus_get_unique_name
);
1434 Qdbus_call_method
= intern ("dbus-call-method");
1435 staticpro (&Qdbus_call_method
);
1436 defsubr (&Sdbus_call_method
);
1438 Qdbus_method_return_internal
= intern ("dbus-method-return-internal");
1439 staticpro (&Qdbus_method_return_internal
);
1440 defsubr (&Sdbus_method_return_internal
);
1442 Qdbus_send_signal
= intern ("dbus-send-signal");
1443 staticpro (&Qdbus_send_signal
);
1444 defsubr (&Sdbus_send_signal
);
1446 Qdbus_register_signal
= intern ("dbus-register-signal");
1447 staticpro (&Qdbus_register_signal
);
1448 defsubr (&Sdbus_register_signal
);
1450 Qdbus_register_method
= intern ("dbus-register-method");
1451 staticpro (&Qdbus_register_method
);
1452 defsubr (&Sdbus_register_method
);
1454 Qdbus_error
= intern ("dbus-error");
1455 staticpro (&Qdbus_error
);
1456 Fput (Qdbus_error
, Qerror_conditions
,
1457 list2 (Qdbus_error
, Qerror
));
1458 Fput (Qdbus_error
, Qerror_message
,
1459 build_string ("D-Bus error"));
1461 QCdbus_system_bus
= intern (":system");
1462 staticpro (&QCdbus_system_bus
);
1464 QCdbus_session_bus
= intern (":session");
1465 staticpro (&QCdbus_session_bus
);
1467 QCdbus_type_byte
= intern (":byte");
1468 staticpro (&QCdbus_type_byte
);
1470 QCdbus_type_boolean
= intern (":boolean");
1471 staticpro (&QCdbus_type_boolean
);
1473 QCdbus_type_int16
= intern (":int16");
1474 staticpro (&QCdbus_type_int16
);
1476 QCdbus_type_uint16
= intern (":uint16");
1477 staticpro (&QCdbus_type_uint16
);
1479 QCdbus_type_int32
= intern (":int32");
1480 staticpro (&QCdbus_type_int32
);
1482 QCdbus_type_uint32
= intern (":uint32");
1483 staticpro (&QCdbus_type_uint32
);
1485 QCdbus_type_int64
= intern (":int64");
1486 staticpro (&QCdbus_type_int64
);
1488 QCdbus_type_uint64
= intern (":uint64");
1489 staticpro (&QCdbus_type_uint64
);
1491 QCdbus_type_double
= intern (":double");
1492 staticpro (&QCdbus_type_double
);
1494 QCdbus_type_string
= intern (":string");
1495 staticpro (&QCdbus_type_string
);
1497 QCdbus_type_object_path
= intern (":object-path");
1498 staticpro (&QCdbus_type_object_path
);
1500 QCdbus_type_signature
= intern (":signature");
1501 staticpro (&QCdbus_type_signature
);
1503 QCdbus_type_array
= intern (":array");
1504 staticpro (&QCdbus_type_array
);
1506 QCdbus_type_variant
= intern (":variant");
1507 staticpro (&QCdbus_type_variant
);
1509 QCdbus_type_struct
= intern (":struct");
1510 staticpro (&QCdbus_type_struct
);
1512 QCdbus_type_dict_entry
= intern (":dict-entry");
1513 staticpro (&QCdbus_type_dict_entry
);
1515 DEFVAR_LISP ("dbus-registered-functions-table",
1516 &Vdbus_registered_functions_table
,
1517 doc
: /* Hash table of registered functions for D-Bus.
1518 The key in the hash table is the list (BUS INTERFACE MEMBER). BUS is
1519 either the symbol `:system' or the symbol `:session'. INTERFACE is a
1520 string which denotes a D-Bus interface, and MEMBER, also a string, is
1521 either a method or a signal INTERFACE is offering. All arguments but
1522 BUS must not be nil.
1524 The value in the hash table is a list of quadruple lists
1525 \((UNAME SERVICE PATH HANDLER) (UNAME SERVICE PATH HANDLER) ...).
1526 SERVICE is the service name as registered, UNAME is the corresponding
1527 unique name. PATH is the object path of the sending object. All of
1528 them can be nil, which means a wildcard then. HANDLER is the function
1529 to be called when a D-Bus message, which matches the key criteria,
1531 /* We initialize Vdbus_registered_functions_table in dbus.el,
1532 because we need to define a hash table function first. */
1533 Vdbus_registered_functions_table
= Qnil
;
1535 DEFVAR_LISP ("dbus-debug", &Vdbus_debug
,
1536 doc
: /* If non-nil, debug messages of D-Bus bindings are raised. */);
1543 Fprovide (intern ("dbusbind"), Qnil
);
1547 #endif /* HAVE_DBUS */
1549 /* arch-tag: 0e828477-b571-4fe4-b559-5c9211bc14b8
1550 (do not change this comment) */