This source file includes following definitions.
- xd_symbol_to_dbus_type
- xd_dbus_type_to_symbol
- XD_OBJECT_TO_STRING
- xd_signature_cat
- xd_signature
- xd_extract_signed
- xd_extract_unsigned
- xd_append_arg
- xd_retrieve_arg
- xd_get_connection_references
- xd_lisp_dbus_to_dbus
- xd_get_connection_address
- xd_find_watch_fd
- xd_add_watch
- xd_remove_watch
- xd_toggle_watch
- xd_close_bus
- DEFUN
- xd_read_message_1
- xd_read_message
- xd_read_queued_messages
- init_dbusbind
- syms_of_dbusbind_for_pdumper
- syms_of_dbusbind
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <config.h>
20
21 #ifdef HAVE_DBUS
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <dbus/dbus.h>
25
26 #include "lisp.h"
27 #include "termhooks.h"
28 #include "keyboard.h"
29 #include "pdumper.h"
30 #include "process.h"
31
32 #ifndef DBUS_NUM_MESSAGE_TYPES
33 #define DBUS_NUM_MESSAGE_TYPES 5
34 #endif
35
36
37
38
39
40 #ifdef interface
41 #undef interface
42 #endif
43
44
45
46
47
48
49
50
51 static Lisp_Object xd_registered_buses;
52
53
54 static bool xd_in_read_queued_messages = 0;
55
56
57
58
59
60
61
62 #define XD_SIGNAL1(arg) \
63 do { \
64 if (xd_in_read_queued_messages) \
65 Fthrow (Qdbus_error, Qnil); \
66 else \
67 xsignal1 (Qdbus_error, arg); \
68 } while (0)
69
70 #define XD_SIGNAL2(arg1, arg2) \
71 do { \
72 if (xd_in_read_queued_messages) \
73 Fthrow (Qdbus_error, Qnil); \
74 else \
75 xsignal2 (Qdbus_error, arg1, arg2); \
76 } while (0)
77
78 #define XD_SIGNAL3(arg1, arg2, arg3) \
79 do { \
80 if (xd_in_read_queued_messages) \
81 Fthrow (Qdbus_error, Qnil); \
82 else \
83 xsignal3 (Qdbus_error, arg1, arg2, arg3); \
84 } while (0)
85
86
87 #define XD_ERROR(error) \
88 do { \
89 \
90 char const *mess = error.message; \
91 char const *nl = strchr (mess, '\n'); \
92 Lisp_Object err = make_string (mess, nl ? nl - mess : strlen (mess)); \
93 dbus_error_free (&error); \
94 XD_SIGNAL1 (err); \
95 } while (0)
96
97
98
99 #ifdef DBUS_DEBUG
100 #define XD_DEBUG_MESSAGE(...) \
101 do { \
102 char s[1024]; \
103 snprintf (s, sizeof s, __VA_ARGS__); \
104 if (!noninteractive) \
105 printf ("%s: %s\n", __func__, s); \
106 message ("%s: %s", __func__, s); \
107 } while (0)
108 #define XD_DEBUG_VALID_LISP_OBJECT_P(object) \
109 do { \
110 if (!valid_lisp_object_p (object)) \
111 { \
112 XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__); \
113 XD_SIGNAL1 (build_string ("Assertion failure")); \
114 } \
115 } while (0)
116
117 #else
118 # define XD_DEBUG_MESSAGE(...) \
119 do { \
120 if (!NILP (Vdbus_debug)) \
121 { \
122 char s[1024]; \
123 snprintf (s, sizeof s, __VA_ARGS__); \
124 message ("%s: %s", __func__, s); \
125 } \
126 } while (0)
127 # define XD_DEBUG_VALID_LISP_OBJECT_P(object)
128 #endif
129
130
131 #ifdef HAVE_DBUS_TYPE_IS_VALID
132 #define XD_BASIC_DBUS_TYPE(type) \
133 (dbus_type_is_valid (type) && dbus_type_is_basic (type))
134 #else
135 #ifdef DBUS_TYPE_UNIX_FD
136 #define XD_BASIC_DBUS_TYPE(type) \
137 ((type == DBUS_TYPE_BYTE) \
138 || (type == DBUS_TYPE_BOOLEAN) \
139 || (type == DBUS_TYPE_INT16) \
140 || (type == DBUS_TYPE_UINT16) \
141 || (type == DBUS_TYPE_INT32) \
142 || (type == DBUS_TYPE_UINT32) \
143 || (type == DBUS_TYPE_INT64) \
144 || (type == DBUS_TYPE_UINT64) \
145 || (type == DBUS_TYPE_DOUBLE) \
146 || (type == DBUS_TYPE_STRING) \
147 || (type == DBUS_TYPE_OBJECT_PATH) \
148 || (type == DBUS_TYPE_SIGNATURE) \
149 || (type == DBUS_TYPE_UNIX_FD))
150 #else
151 #define XD_BASIC_DBUS_TYPE(type) \
152 ((type == DBUS_TYPE_BYTE) \
153 || (type == DBUS_TYPE_BOOLEAN) \
154 || (type == DBUS_TYPE_INT16) \
155 || (type == DBUS_TYPE_UINT16) \
156 || (type == DBUS_TYPE_INT32) \
157 || (type == DBUS_TYPE_UINT32) \
158 || (type == DBUS_TYPE_INT64) \
159 || (type == DBUS_TYPE_UINT64) \
160 || (type == DBUS_TYPE_DOUBLE) \
161 || (type == DBUS_TYPE_STRING) \
162 || (type == DBUS_TYPE_OBJECT_PATH) \
163 || (type == DBUS_TYPE_SIGNATURE))
164 #endif
165 #endif
166
167
168
169
170
171
172 static int
173 xd_symbol_to_dbus_type (Lisp_Object object)
174 {
175 return
176 (EQ (object, QCbyte) ? DBUS_TYPE_BYTE
177 : EQ (object, QCboolean) ? DBUS_TYPE_BOOLEAN
178 : EQ (object, QCint16) ? DBUS_TYPE_INT16
179 : EQ (object, QCuint16) ? DBUS_TYPE_UINT16
180 : EQ (object, QCint32) ? DBUS_TYPE_INT32
181 : EQ (object, QCuint32) ? DBUS_TYPE_UINT32
182 : EQ (object, QCint64) ? DBUS_TYPE_INT64
183 : EQ (object, QCuint64) ? DBUS_TYPE_UINT64
184 : EQ (object, QCdouble) ? DBUS_TYPE_DOUBLE
185 : EQ (object, QCstring) ? DBUS_TYPE_STRING
186 : EQ (object, QCobject_path) ? DBUS_TYPE_OBJECT_PATH
187 : EQ (object, QCsignature) ? DBUS_TYPE_SIGNATURE
188 #ifdef DBUS_TYPE_UNIX_FD
189 : EQ (object, QCunix_fd) ? DBUS_TYPE_UNIX_FD
190 #endif
191 : EQ (object, QCarray) ? DBUS_TYPE_ARRAY
192 : EQ (object, QCvariant) ? DBUS_TYPE_VARIANT
193 : EQ (object, QCstruct) ? DBUS_TYPE_STRUCT
194 : EQ (object, QCdict_entry) ? DBUS_TYPE_DICT_ENTRY
195 : DBUS_TYPE_INVALID);
196 }
197
198
199 static Lisp_Object
200 xd_dbus_type_to_symbol (int type)
201 {
202 return
203 (type == DBUS_TYPE_BYTE) ? QCbyte
204 : (type == DBUS_TYPE_BOOLEAN) ? QCboolean
205 : (type == DBUS_TYPE_INT16) ? QCint16
206 : (type == DBUS_TYPE_UINT16) ? QCuint16
207 : (type == DBUS_TYPE_INT32) ? QCint32
208 : (type == DBUS_TYPE_UINT32) ? QCuint32
209 : (type == DBUS_TYPE_INT64) ? QCint64
210 : (type == DBUS_TYPE_UINT64) ? QCuint64
211 : (type == DBUS_TYPE_DOUBLE) ? QCdouble
212 : (type == DBUS_TYPE_STRING) ? QCstring
213 : (type == DBUS_TYPE_OBJECT_PATH) ? QCobject_path
214 : (type == DBUS_TYPE_SIGNATURE) ? QCsignature
215 #ifdef DBUS_TYPE_UNIX_FD
216 : (type == DBUS_TYPE_UNIX_FD) ? QCunix_fd
217 #endif
218 : (type == DBUS_TYPE_ARRAY) ? QCarray
219 : (type == DBUS_TYPE_VARIANT) ? QCvariant
220 : (type == DBUS_TYPE_STRUCT) ? QCstruct
221 : (type == DBUS_TYPE_DICT_ENTRY) ? QCdict_entry
222 : Qnil;
223 }
224
225 #define XD_KEYWORDP(object) !NILP (Fkeywordp (object))
226
227
228 #define XD_DBUS_TYPE_P(object) \
229 XD_KEYWORDP (object) && \
230 ((xd_symbol_to_dbus_type (object) != DBUS_TYPE_INVALID))
231
232
233
234
235
236 #define XD_OBJECT_TO_DBUS_TYPE(object) \
237 ((EQ (object, Qt) || NILP (object)) ? DBUS_TYPE_BOOLEAN \
238 : (FIXNATP (object)) ? DBUS_TYPE_UINT32 \
239 : (FIXNUMP (object)) ? DBUS_TYPE_INT32 \
240 : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \
241 : (STRINGP (object)) ? DBUS_TYPE_STRING \
242 : (XD_DBUS_TYPE_P (object)) ? xd_symbol_to_dbus_type (object) \
243 : (CONSP (object)) \
244 ? ((XD_DBUS_TYPE_P (XCAR (object))) \
245 ? ((XD_BASIC_DBUS_TYPE (xd_symbol_to_dbus_type (XCAR (object)))) \
246 ? DBUS_TYPE_ARRAY \
247 : xd_symbol_to_dbus_type (XCAR (object))) \
248 : DBUS_TYPE_ARRAY) \
249 : DBUS_TYPE_INVALID)
250
251
252 #define XD_NEXT_VALUE(object) \
253 ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object)
254
255
256
257 #define XD_MESSAGE_TYPE_TO_STRING(mtype) \
258 ((mtype == DBUS_MESSAGE_TYPE_INVALID) \
259 ? "DBUS_MESSAGE_TYPE_INVALID" \
260 : (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) \
261 ? "DBUS_MESSAGE_TYPE_METHOD_CALL" \
262 : (mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN) \
263 ? "DBUS_MESSAGE_TYPE_METHOD_RETURN" \
264 : (mtype == DBUS_MESSAGE_TYPE_ERROR) \
265 ? "DBUS_MESSAGE_TYPE_ERROR" \
266 : "DBUS_MESSAGE_TYPE_SIGNAL")
267
268
269
270 static char *
271 XD_OBJECT_TO_STRING (Lisp_Object object)
272 {
273 AUTO_STRING (format, "%s");
274 return SSDATA (CALLN (Fformat, format, object));
275 }
276
277 #define XD_DBUS_VALIDATE_BUS_ADDRESS(bus) \
278 do { \
279 char const *session_bus_address = egetenv ("DBUS_SESSION_BUS_ADDRESS"); \
280 if (STRINGP (bus)) \
281 { \
282 DBusAddressEntry **entries; \
283 int len; \
284 DBusError derror; \
285 dbus_error_init (&derror); \
286 if (!dbus_parse_address (SSDATA (bus), &entries, &len, &derror)) \
287 XD_ERROR (derror); \
288 \
289 dbus_error_free (&derror); \
290 dbus_address_entries_free (entries); \
291 \
292 if ((session_bus_address != NULL) \
293 && (!NILP (Fstring_equal \
294 (bus, build_string (session_bus_address))))) \
295 bus = QCsession; \
296 } \
297 \
298 else \
299 { \
300 CHECK_SYMBOL (bus); \
301 if (!(EQ (bus, QCsystem) || EQ (bus, QCsession) \
302 || EQ (bus, QCsystem_private) \
303 || EQ (bus, QCsession_private))) \
304 XD_SIGNAL2 (build_string ("Wrong bus name"), bus); \
305 \
306 if ((EQ (bus, QCsession) || EQ (bus, QCsession_private)) \
307 && session_bus_address == NULL) \
308 XD_SIGNAL2 (build_string ("No connection to bus"), bus); \
309 } \
310 } while (0)
311
312 #if (HAVE_DBUS_VALIDATE_BUS_NAME || HAVE_DBUS_VALIDATE_PATH \
313 || HAVE_DBUS_VALIDATE_INTERFACE || HAVE_DBUS_VALIDATE_MEMBER)
314 #define XD_DBUS_VALIDATE_OBJECT(object, func) \
315 do { \
316 if (!NILP (object)) \
317 { \
318 DBusError derror; \
319 CHECK_STRING (object); \
320 dbus_error_init (&derror); \
321 if (!func (SSDATA (object), &derror)) \
322 XD_ERROR (derror); \
323 \
324 dbus_error_free (&derror); \
325 } \
326 } while (0)
327 #endif
328
329 #if HAVE_DBUS_VALIDATE_BUS_NAME
330 #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \
331 XD_DBUS_VALIDATE_OBJECT(bus_name, dbus_validate_bus_name);
332 #else
333 #define XD_DBUS_VALIDATE_BUS_NAME(bus_name) \
334 if (!NILP (bus_name)) CHECK_STRING (bus_name);
335 #endif
336
337 #if HAVE_DBUS_VALIDATE_PATH
338 #define XD_DBUS_VALIDATE_PATH(path) \
339 XD_DBUS_VALIDATE_OBJECT(path, dbus_validate_path);
340 #else
341 #define XD_DBUS_VALIDATE_PATH(path) \
342 if (!NILP (path)) CHECK_STRING (path);
343 #endif
344
345 #if HAVE_DBUS_VALIDATE_INTERFACE
346 #define XD_DBUS_VALIDATE_INTERFACE(interface) \
347 XD_DBUS_VALIDATE_OBJECT(interface, dbus_validate_interface);
348 #else
349 #define XD_DBUS_VALIDATE_INTERFACE(interface) \
350 if (!NILP (interface)) CHECK_STRING (interface);
351 #endif
352
353 #if HAVE_DBUS_VALIDATE_MEMBER
354 #define XD_DBUS_VALIDATE_MEMBER(member) \
355 XD_DBUS_VALIDATE_OBJECT(member, dbus_validate_member);
356 #else
357 #define XD_DBUS_VALIDATE_MEMBER(member) \
358 if (!NILP (member)) CHECK_STRING (member);
359 #endif
360
361
362
363 static void
364 xd_signature_cat (char *signature, char const *x)
365 {
366 ptrdiff_t siglen = strlen (signature);
367 ptrdiff_t xlen = strlen (x);
368 if (DBUS_MAXIMUM_SIGNATURE_LENGTH - xlen <= siglen)
369 string_overflow ();
370 strcpy (signature + siglen, x);
371 }
372
373
374
375
376
377
378
379
380 static void
381 xd_signature (char *signature, int dtype, int parent_type, Lisp_Object object)
382 {
383 int subtype;
384 Lisp_Object elt;
385 char const *subsig;
386 char x[DBUS_MAXIMUM_SIGNATURE_LENGTH];
387
388 elt = object;
389
390 switch (dtype)
391 {
392 case DBUS_TYPE_BYTE:
393 case DBUS_TYPE_UINT16:
394 CHECK_FIXNAT (object);
395 sprintf (signature, "%c", dtype);
396 break;
397
398 case DBUS_TYPE_BOOLEAN:
399
400 if (EQ (QCboolean, object))
401 wrong_type_argument (Qbooleanp, object);
402 sprintf (signature, "%c", dtype);
403 break;
404
405 case DBUS_TYPE_INT16:
406 CHECK_FIXNUM (object);
407 sprintf (signature, "%c", dtype);
408 break;
409
410 case DBUS_TYPE_UINT32:
411 case DBUS_TYPE_UINT64:
412 #ifdef DBUS_TYPE_UNIX_FD
413 case DBUS_TYPE_UNIX_FD:
414 #endif
415 case DBUS_TYPE_INT32:
416 case DBUS_TYPE_INT64:
417 case DBUS_TYPE_DOUBLE:
418 CHECK_NUMBER (object);
419 sprintf (signature, "%c", dtype);
420 break;
421
422 case DBUS_TYPE_STRING:
423 case DBUS_TYPE_OBJECT_PATH:
424 case DBUS_TYPE_SIGNATURE:
425
426
427 if (dtype == DBUS_TYPE_OBJECT_PATH)
428 XD_DBUS_VALIDATE_PATH (object)
429 else
430 CHECK_STRING (object);
431 sprintf (signature, "%c", dtype);
432 break;
433
434 case DBUS_TYPE_ARRAY:
435
436
437
438 CHECK_CONS (object);
439
440
441 if (EQ (QCarray, XCAR (elt)))
442 elt = XD_NEXT_VALUE (elt);
443
444
445
446 if (NILP (elt))
447 {
448 subtype = DBUS_TYPE_STRING;
449 subsig = DBUS_TYPE_STRING_AS_STRING;
450 }
451 else
452 {
453 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
454 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
455 subsig = x;
456 }
457
458
459
460
461 if (subtype == DBUS_TYPE_SIGNATURE)
462 {
463 Lisp_Object elt1 = XD_NEXT_VALUE (elt);
464 if (CONSP (elt1) && STRINGP (XCAR (elt1)) && NILP (XCDR (elt1)))
465 {
466 subsig = SSDATA (XCAR (elt1));
467 elt = Qnil;
468 }
469 }
470
471 while (!NILP (elt))
472 {
473 char x[DBUS_MAXIMUM_SIGNATURE_LENGTH];
474 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
475 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
476 if (strcmp (subsig, x) != 0)
477 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (elt));
478 elt = CDR_SAFE (XD_NEXT_VALUE (elt));
479 }
480
481 signature[0] = dtype;
482 signature[1] = '\0';
483 xd_signature_cat (signature, subsig);
484 break;
485
486 case DBUS_TYPE_VARIANT:
487
488 CHECK_CONS (object);
489
490 elt = XD_NEXT_VALUE (elt);
491 CHECK_CONS (elt);
492 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
493 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
494
495 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
496 wrong_type_argument (intern ("D-Bus"),
497 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt))));
498
499 sprintf (signature, "%c", dtype);
500 break;
501
502 case DBUS_TYPE_STRUCT:
503
504
505 CHECK_CONS (object);
506
507 elt = XD_NEXT_VALUE (elt);
508 CHECK_CONS (elt);
509
510
511
512 sprintf (signature, "%c", DBUS_STRUCT_BEGIN_CHAR );
513 while (!NILP (elt))
514 {
515 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
516 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
517 xd_signature_cat (signature, x);
518 elt = CDR_SAFE (XD_NEXT_VALUE (elt));
519 }
520 xd_signature_cat (signature, DBUS_STRUCT_END_CHAR_AS_STRING);
521 break;
522
523 case DBUS_TYPE_DICT_ENTRY:
524
525
526
527 CHECK_CONS (object);
528
529
530 if (parent_type != DBUS_TYPE_ARRAY)
531 wrong_type_argument (intern ("D-Bus"), object);
532
533
534
535 sprintf (signature, "%c", DBUS_DICT_ENTRY_BEGIN_CHAR);
536
537
538 elt = XD_NEXT_VALUE (elt);
539 CHECK_CONS (elt);
540 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
541 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
542 xd_signature_cat (signature, x);
543
544 if (!XD_BASIC_DBUS_TYPE (subtype))
545 wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt)));
546
547
548 elt = CDR_SAFE (XD_NEXT_VALUE (elt));
549 CHECK_CONS (elt);
550 subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
551 xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
552 xd_signature_cat (signature, x);
553
554 if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
555 wrong_type_argument (intern ("D-Bus"),
556 CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt))));
557
558
559 xd_signature_cat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
560 break;
561
562 default:
563 wrong_type_argument (intern ("D-Bus"), object);
564 }
565
566 XD_DEBUG_MESSAGE ("%s", signature);
567 }
568
569
570 static intmax_t
571 xd_extract_signed (Lisp_Object x, intmax_t lo, intmax_t hi)
572 {
573 CHECK_NUMBER (x);
574 if (INTEGERP (x))
575 {
576 intmax_t i;
577 if (integer_to_intmax (x, &i) && lo <= i && i <= hi)
578 return i;
579 }
580 else
581 {
582 double d = XFLOAT_DATA (x);
583 if (lo <= d && d < 1.0 + hi)
584 {
585 intmax_t n = d;
586 if (n == d)
587 return n;
588 }
589 }
590
591 if (xd_in_read_queued_messages)
592 Fthrow (Qdbus_error, Qnil);
593 else
594 args_out_of_range_3 (x, INT_TO_INTEGER (lo), INT_TO_INTEGER (hi));
595 }
596
597
598 static uintmax_t
599 xd_extract_unsigned (Lisp_Object x, uintmax_t hi)
600 {
601 CHECK_NUMBER (x);
602 if (INTEGERP (x))
603 {
604 uintmax_t i;
605 if (integer_to_uintmax (x, &i) && i <= hi)
606 return i;
607 }
608 else
609 {
610 double d = XFLOAT_DATA (x);
611 if (0 <= d && d < 1.0 + hi)
612 {
613 uintmax_t n = d;
614 if (n == d)
615 return n;
616 }
617 }
618
619 if (xd_in_read_queued_messages)
620 Fthrow (Qdbus_error, Qnil);
621 else
622 args_out_of_range_3 (x, make_fixnum (0), INT_TO_INTEGER (hi));
623 }
624
625
626
627
628
629
630 static void
631 xd_append_arg (int dtype, Lisp_Object object, DBusMessageIter *iter)
632 {
633 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
634 DBusMessageIter subiter;
635
636 if (XD_BASIC_DBUS_TYPE (dtype))
637 switch (dtype)
638 {
639 case DBUS_TYPE_BYTE:
640 CHECK_FIXNAT (object);
641 {
642 unsigned char val = XFIXNAT (object) & 0xFF;
643 XD_DEBUG_MESSAGE ("%c %u", dtype, val);
644 if (!dbus_message_iter_append_basic (iter, dtype, &val))
645 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
646 return;
647 }
648
649 case DBUS_TYPE_BOOLEAN:
650
651 if (EQ (QCboolean, object))
652 wrong_type_argument (Qbooleanp, object);
653 {
654 dbus_bool_t val = (NILP (object)) ? FALSE : TRUE;
655 XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
656 if (!dbus_message_iter_append_basic (iter, dtype, &val))
657 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
658 return;
659 }
660
661 case DBUS_TYPE_INT16:
662 {
663 dbus_int16_t val =
664 xd_extract_signed (object,
665 TYPE_MINIMUM (dbus_int16_t),
666 TYPE_MAXIMUM (dbus_int16_t));
667 int pval = val;
668 XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
669 if (!dbus_message_iter_append_basic (iter, dtype, &val))
670 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
671 return;
672 }
673
674 case DBUS_TYPE_UINT16:
675 {
676 dbus_uint16_t val =
677 xd_extract_unsigned (object,
678 TYPE_MAXIMUM (dbus_uint16_t));
679 unsigned int pval = val;
680 XD_DEBUG_MESSAGE ("%c %u", dtype, pval);
681 if (!dbus_message_iter_append_basic (iter, dtype, &val))
682 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
683 return;
684 }
685
686 case DBUS_TYPE_INT32:
687 {
688 dbus_int32_t val =
689 xd_extract_signed (object,
690 TYPE_MINIMUM (dbus_int32_t),
691 TYPE_MAXIMUM (dbus_int32_t));
692 int pval = val;
693 XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
694 if (!dbus_message_iter_append_basic (iter, dtype, &val))
695 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
696 return;
697 }
698
699 case DBUS_TYPE_UINT32:
700 #ifdef DBUS_TYPE_UNIX_FD
701 case DBUS_TYPE_UNIX_FD:
702 #endif
703 {
704 dbus_uint32_t val =
705 xd_extract_unsigned (object,
706 TYPE_MAXIMUM (dbus_uint32_t));
707 unsigned int pval = val;
708 XD_DEBUG_MESSAGE ("%c %u", dtype, pval);
709 if (!dbus_message_iter_append_basic (iter, dtype, &val))
710 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
711 return;
712 }
713
714 case DBUS_TYPE_INT64:
715 {
716 dbus_int64_t val =
717 xd_extract_signed (object,
718 TYPE_MINIMUM (dbus_int64_t),
719 TYPE_MAXIMUM (dbus_int64_t));
720 intmax_t pval = val;
721 XD_DEBUG_MESSAGE ("%c %"PRIdMAX, dtype, pval);
722 if (!dbus_message_iter_append_basic (iter, dtype, &val))
723 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
724 return;
725 }
726
727 case DBUS_TYPE_UINT64:
728 {
729 dbus_uint64_t val =
730 xd_extract_unsigned (object,
731 TYPE_MAXIMUM (dbus_uint64_t));
732 uintmax_t pval = val;
733 XD_DEBUG_MESSAGE ("%c %"PRIuMAX, dtype, pval);
734 if (!dbus_message_iter_append_basic (iter, dtype, &val))
735 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
736 return;
737 }
738
739 case DBUS_TYPE_DOUBLE:
740 {
741 double val = extract_float (object);
742 XD_DEBUG_MESSAGE ("%c %f", dtype, val);
743 if (!dbus_message_iter_append_basic (iter, dtype, &val))
744 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
745 return;
746 }
747
748 case DBUS_TYPE_STRING:
749 case DBUS_TYPE_OBJECT_PATH:
750 case DBUS_TYPE_SIGNATURE:
751
752
753 if (dtype == DBUS_TYPE_OBJECT_PATH)
754 XD_DBUS_VALIDATE_PATH (object)
755 else
756 CHECK_STRING (object);
757 {
758
759
760
761
762 char *val = SSDATA (object);
763 XD_DEBUG_MESSAGE ("%c %s", dtype, val);
764 if (!dbus_message_iter_append_basic (iter, dtype, &val))
765 XD_SIGNAL2 (build_string ("Unable to append argument"), object);
766 return;
767 }
768 }
769
770 else
771 {
772
773
774
775 if (!XD_BASIC_DBUS_TYPE (XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object))))
776 object = XD_NEXT_VALUE (object);
777
778
779 switch (dtype)
780 {
781 case DBUS_TYPE_ARRAY:
782
783
784
785
786 if (NILP (object))
787
788
789 strcpy (signature, DBUS_TYPE_STRING_AS_STRING);
790
791 else
792 {
793
794
795
796 if (CONSP (object) && (XD_OBJECT_TO_DBUS_TYPE (XCAR (object))
797 == DBUS_TYPE_SIGNATURE))
798 {
799 Lisp_Object val = XD_NEXT_VALUE (object);
800 if (CONSP (val) && STRINGP (XCAR (val)) && NILP (XCDR (val))
801 && SBYTES (XCAR (val)) < DBUS_MAXIMUM_SIGNATURE_LENGTH)
802 {
803 lispstpcpy (signature, XCAR (val));
804 object = Qnil;
805 }
806 }
807
808 if (!NILP (object))
809 xd_signature (signature,
810 XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)),
811 dtype, CAR_SAFE (XD_NEXT_VALUE (object)));
812 }
813
814 XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature,
815 XD_OBJECT_TO_STRING (object));
816 if (!dbus_message_iter_open_container (iter, dtype,
817 signature, &subiter))
818 XD_SIGNAL3 (build_string ("Cannot open container"),
819 make_fixnum (dtype), build_string (signature));
820 break;
821
822 case DBUS_TYPE_VARIANT:
823
824 xd_signature (signature, XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)),
825 dtype, CAR_SAFE (XD_NEXT_VALUE (object)));
826
827 XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature,
828 XD_OBJECT_TO_STRING (object));
829 if (!dbus_message_iter_open_container (iter, dtype,
830 signature, &subiter))
831 XD_SIGNAL3 (build_string ("Cannot open container"),
832 make_fixnum (dtype), build_string (signature));
833 break;
834
835 case DBUS_TYPE_STRUCT:
836 case DBUS_TYPE_DICT_ENTRY:
837
838 XD_DEBUG_MESSAGE ("%c %s", dtype, XD_OBJECT_TO_STRING (object));
839 if (!dbus_message_iter_open_container (iter, dtype, NULL, &subiter))
840 XD_SIGNAL2 (build_string ("Cannot open container"),
841 make_fixnum (dtype));
842 break;
843 }
844
845
846 while (!NILP (object))
847 {
848 dtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object));
849 object = XD_NEXT_VALUE (object);
850
851 xd_append_arg (dtype, CAR_SAFE (object), &subiter);
852
853 object = CDR_SAFE (object);
854 }
855
856
857 if (!dbus_message_iter_close_container (iter, &subiter))
858 XD_SIGNAL2 (build_string ("Cannot close container"),
859 make_fixnum (dtype));
860 }
861 }
862
863
864
865
866
867 static Lisp_Object
868 xd_retrieve_arg (int dtype, DBusMessageIter *iter)
869 {
870
871 switch (dtype)
872 {
873 case DBUS_TYPE_BYTE:
874 {
875 unsigned int val;
876 dbus_message_iter_get_basic (iter, &val);
877 val = val & 0xFF;
878 XD_DEBUG_MESSAGE ("%c %u", dtype, val);
879 return list2 (xd_dbus_type_to_symbol (dtype), make_fixnum (val));
880 }
881
882 case DBUS_TYPE_BOOLEAN:
883 {
884 dbus_bool_t val;
885 dbus_message_iter_get_basic (iter, &val);
886 XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
887 return list2 (xd_dbus_type_to_symbol (dtype),
888 (val == FALSE) ? Qnil : Qt);
889 }
890
891 case DBUS_TYPE_INT16:
892 {
893 dbus_int16_t val;
894 int pval;
895 dbus_message_iter_get_basic (iter, &val);
896 pval = val;
897 XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
898 return list2 (xd_dbus_type_to_symbol (dtype), make_fixnum (val));
899 }
900
901 case DBUS_TYPE_UINT16:
902 {
903 dbus_uint16_t val;
904 int pval;
905 dbus_message_iter_get_basic (iter, &val);
906 pval = val;
907 XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
908 return list2 (xd_dbus_type_to_symbol (dtype), make_fixnum (val));
909 }
910
911 case DBUS_TYPE_INT32:
912 {
913 dbus_int32_t val;
914 int pval;
915 dbus_message_iter_get_basic (iter, &val);
916 pval = val;
917 XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
918 return list2 (xd_dbus_type_to_symbol (dtype), INT_TO_INTEGER (val));
919 }
920
921 case DBUS_TYPE_UINT32:
922 #ifdef DBUS_TYPE_UNIX_FD
923 case DBUS_TYPE_UNIX_FD:
924 #endif
925 {
926 dbus_uint32_t val;
927 unsigned int pval;
928 dbus_message_iter_get_basic (iter, &val);
929 pval = val;
930 XD_DEBUG_MESSAGE ("%c %u", dtype, pval);
931 return list2 (xd_dbus_type_to_symbol (dtype), INT_TO_INTEGER (val));
932 }
933
934 case DBUS_TYPE_INT64:
935 {
936 dbus_int64_t val;
937 dbus_message_iter_get_basic (iter, &val);
938 intmax_t pval = val;
939 XD_DEBUG_MESSAGE ("%c %"PRIdMAX, dtype, pval);
940 return list2 (xd_dbus_type_to_symbol (dtype), INT_TO_INTEGER (val));
941 }
942
943 case DBUS_TYPE_UINT64:
944 {
945 dbus_uint64_t val;
946 dbus_message_iter_get_basic (iter, &val);
947 uintmax_t pval = val;
948 XD_DEBUG_MESSAGE ("%c %"PRIuMAX, dtype, pval);
949 return list2 (xd_dbus_type_to_symbol (dtype), INT_TO_INTEGER (val));
950 }
951
952 case DBUS_TYPE_DOUBLE:
953 {
954 double val;
955 dbus_message_iter_get_basic (iter, &val);
956 XD_DEBUG_MESSAGE ("%c %f", dtype, val);
957 return list2 (xd_dbus_type_to_symbol (dtype), make_float (val));
958 }
959
960 case DBUS_TYPE_STRING:
961 case DBUS_TYPE_OBJECT_PATH:
962 case DBUS_TYPE_SIGNATURE:
963 {
964 char *val;
965 dbus_message_iter_get_basic (iter, &val);
966 XD_DEBUG_MESSAGE ("%c %s", dtype, val);
967 return list2 (xd_dbus_type_to_symbol (dtype), build_string (val));
968 }
969
970 case DBUS_TYPE_ARRAY:
971 case DBUS_TYPE_VARIANT:
972 case DBUS_TYPE_STRUCT:
973 case DBUS_TYPE_DICT_ENTRY:
974 {
975 Lisp_Object result;
976 DBusMessageIter subiter;
977 int subtype;
978 result = Qnil;
979 dbus_message_iter_recurse (iter, &subiter);
980 while ((subtype = dbus_message_iter_get_arg_type (&subiter))
981 != DBUS_TYPE_INVALID)
982 {
983 result = Fcons (xd_retrieve_arg (subtype, &subiter), result);
984 dbus_message_iter_next (&subiter);
985 }
986 XD_DEBUG_MESSAGE ("%c %s", dtype, XD_OBJECT_TO_STRING (result));
987 return Fcons (xd_dbus_type_to_symbol (dtype), Fnreverse (result));
988 }
989
990 default:
991 XD_DEBUG_MESSAGE ("DBusType '%c' not supported", dtype);
992 return Qnil;
993 }
994 }
995
996
997 static ptrdiff_t
998 xd_get_connection_references (DBusConnection *connection)
999 {
1000 ptrdiff_t *refcount;
1001
1002
1003
1004
1005 refcount = (void *) &connection;
1006 refcount = (void *) *refcount;
1007 return *refcount;
1008 }
1009
1010
1011 static DBusConnection *
1012 xd_lisp_dbus_to_dbus (Lisp_Object bus)
1013 {
1014 return xmint_pointer (bus);
1015 }
1016
1017
1018
1019
1020 static DBusConnection *
1021 xd_get_connection_address (Lisp_Object bus)
1022 {
1023 DBusConnection *connection;
1024 Lisp_Object val;
1025
1026 val = CDR_SAFE (Fassoc (bus, xd_registered_buses, Qnil));
1027 if (NILP (val))
1028 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
1029 else
1030 connection = xd_lisp_dbus_to_dbus (val);
1031
1032 if (!dbus_connection_get_is_connected (connection))
1033 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
1034
1035 return connection;
1036 }
1037
1038
1039 static int
1040 xd_find_watch_fd (DBusWatch *watch)
1041 {
1042 #if HAVE_DBUS_WATCH_GET_UNIX_FD
1043
1044 int fd = dbus_watch_get_unix_fd (watch);
1045 if (fd == -1)
1046 fd = dbus_watch_get_socket (watch);
1047 #else
1048 int fd = dbus_watch_get_fd (watch);
1049 #endif
1050 return fd;
1051 }
1052
1053
1054 static void xd_read_queued_messages (int fd, void *data);
1055
1056
1057 static dbus_bool_t
1058 xd_add_watch (DBusWatch *watch, void *data)
1059 {
1060 unsigned int flags = dbus_watch_get_flags (watch);
1061 int fd = xd_find_watch_fd (watch);
1062
1063 XD_DEBUG_MESSAGE ("fd %d, write %u, enabled %u",
1064 fd, flags & DBUS_WATCH_WRITABLE,
1065 dbus_watch_get_enabled (watch));
1066
1067 if (fd == -1)
1068 return FALSE;
1069
1070 if (dbus_watch_get_enabled (watch))
1071 {
1072 if (flags & DBUS_WATCH_WRITABLE)
1073 add_write_fd (fd, xd_read_queued_messages, data);
1074 if (flags & DBUS_WATCH_READABLE)
1075 add_read_fd (fd, xd_read_queued_messages, data);
1076 }
1077 return TRUE;
1078 }
1079
1080
1081
1082
1083 static void
1084 xd_remove_watch (DBusWatch *watch, void *data)
1085 {
1086 unsigned int flags = dbus_watch_get_flags (watch);
1087 int fd = xd_find_watch_fd (watch);
1088
1089 XD_DEBUG_MESSAGE ("fd %d", fd);
1090
1091 if (fd == -1)
1092 return;
1093
1094
1095 #if 0
1096
1097 if (XSYMBOL (QCsession) == data) || (XSYMBOL (QCsession_private) == data)
1098 {
1099 XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
1100 unsetenv ("DBUS_SESSION_BUS_ADDRESS");
1101 }
1102 #endif
1103
1104 if (flags & DBUS_WATCH_WRITABLE)
1105 delete_write_fd (fd);
1106 if (flags & DBUS_WATCH_READABLE)
1107 delete_read_fd (fd);
1108 }
1109
1110
1111 static void
1112 xd_toggle_watch (DBusWatch *watch, void *data)
1113 {
1114 if (dbus_watch_get_enabled (watch))
1115 xd_add_watch (watch, data);
1116 else
1117 xd_remove_watch (watch, data);
1118 }
1119
1120
1121 static void
1122 xd_close_bus (Lisp_Object bus)
1123 {
1124 DBusConnection *connection;
1125 Lisp_Object val;
1126 Lisp_Object busobj;
1127
1128
1129 val = Fassoc (bus, xd_registered_buses, Qnil);
1130 if (NILP (val))
1131 return;
1132
1133 busobj = CDR_SAFE (val);
1134 if (NILP (busobj)) {
1135 xd_registered_buses = Fdelete (val, xd_registered_buses);
1136 return;
1137 }
1138
1139
1140 connection = xd_lisp_dbus_to_dbus (busobj);
1141
1142 if (xd_get_connection_references (connection) == 1)
1143 {
1144
1145 XD_DEBUG_MESSAGE ("Close connection to bus %s",
1146 XD_OBJECT_TO_STRING (bus));
1147 dbus_connection_close (connection);
1148
1149 xd_registered_buses = Fdelete (val, xd_registered_buses);
1150 }
1151
1152 else
1153
1154 dbus_connection_unref (connection);
1155
1156
1157 return;
1158 }
1159
1160 DEFUN ("dbus--init-bus", Fdbus__init_bus, Sdbus__init_bus, 1, 2, 0,
1161 doc:
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189 )
1190 (Lisp_Object bus, Lisp_Object private)
1191 {
1192 DBusConnection *connection;
1193 DBusError derror;
1194 Lisp_Object val;
1195 ptrdiff_t refcount;
1196
1197
1198 if (!NILP (private))
1199 bus = EQ (bus, QCsystem)
1200 ? QCsystem_private
1201 : EQ (bus, QCsession) ? QCsession_private : bus;
1202 XD_DBUS_VALIDATE_BUS_ADDRESS (bus);
1203
1204
1205 xd_close_bus (bus);
1206
1207
1208 val = Fassoc (bus, xd_registered_buses, Qnil);
1209 if (!NILP (val))
1210 {
1211 connection = xd_get_connection_address (bus);
1212 dbus_connection_ref (connection);
1213 }
1214
1215 else
1216 {
1217
1218 dbus_error_init (&derror);
1219
1220
1221 if (STRINGP (bus))
1222 if (NILP (private))
1223 connection = dbus_connection_open (SSDATA (bus), &derror);
1224 else
1225 connection = dbus_connection_open_private (SSDATA (bus), &derror);
1226
1227 else
1228 {
1229 DBusBusType bustype
1230 = EQ (bus, QCsystem) || EQ (bus, QCsystem_private)
1231 ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION;
1232 if (NILP (private))
1233 connection = dbus_bus_get (bustype, &derror);
1234 else
1235 connection = dbus_bus_get_private (bustype, &derror);
1236 }
1237
1238 if (dbus_error_is_set (&derror))
1239 XD_ERROR (derror);
1240
1241 if (connection == NULL)
1242 XD_SIGNAL2 (build_string ("No connection to bus"), bus);
1243
1244
1245
1246
1247
1248 if (STRINGP (bus))
1249 dbus_bus_register (connection, &derror);
1250 else
1251 dbus_connection_set_exit_on_disconnect (connection, FALSE);
1252
1253 if (dbus_error_is_set (&derror))
1254 XD_ERROR (derror);
1255
1256
1257
1258 if (!dbus_connection_set_watch_functions (connection,
1259 xd_add_watch,
1260 xd_remove_watch,
1261 xd_toggle_watch,
1262 XD_KEYWORDP (bus)
1263 ? (void *) XSYMBOL (bus)
1264 : (void *) XSTRING (bus),
1265 NULL))
1266 XD_SIGNAL1 (build_string ("Cannot add watch functions"));
1267
1268
1269 val = make_mint_ptr (connection);
1270 xd_registered_buses = Fcons (Fcons (bus, val), xd_registered_buses);
1271
1272
1273 dbus_error_free (&derror);
1274 }
1275
1276 XD_DEBUG_MESSAGE ("Registered buses: %s",
1277 XD_OBJECT_TO_STRING (xd_registered_buses));
1278
1279
1280 refcount = xd_get_connection_references (connection);
1281 XD_DEBUG_MESSAGE ("Bus %s, Reference counter %"pD"d",
1282 XD_OBJECT_TO_STRING (bus), refcount);
1283 return make_fixnum (refcount);
1284 }
1285
1286 DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name,
1287 1, 1, 0,
1288 doc: )
1289 (Lisp_Object bus)
1290 {
1291 DBusConnection *connection;
1292 const char *name;
1293
1294
1295 XD_DBUS_VALIDATE_BUS_ADDRESS (bus);
1296
1297
1298 connection = xd_get_connection_address (bus);
1299
1300
1301 name = dbus_bus_get_unique_name (connection);
1302 if (name == NULL)
1303 XD_SIGNAL1 (build_string ("No unique name available"));
1304
1305
1306 return build_string (name);
1307 }
1308
1309 DEFUN ("dbus-message-internal", Fdbus_message_internal, Sdbus_message_internal,
1310 4, MANY, 0,
1311 doc:
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337 )
1338 (ptrdiff_t nargs, Lisp_Object *args)
1339 {
1340 Lisp_Object message_type, bus, service, handler;
1341 Lisp_Object path = Qnil;
1342 Lisp_Object interface = Qnil;
1343 Lisp_Object member = Qnil;
1344 Lisp_Object error_name = Qnil;
1345 Lisp_Object result;
1346 DBusConnection *connection;
1347 DBusMessage *dmessage;
1348 DBusMessageIter iter;
1349 int dtype;
1350 int mtype;
1351 dbus_uint32_t serial = 0;
1352 unsigned int ui_serial;
1353 int timeout = -1;
1354 ptrdiff_t count, count0;
1355 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1356
1357
1358 message_type = args[0];
1359 bus = args[1];
1360 service = args[2];
1361 handler = Qnil;
1362
1363 CHECK_FIXNAT (message_type);
1364 if (! (DBUS_MESSAGE_TYPE_INVALID <= XFIXNAT (message_type)
1365 && XFIXNAT (message_type) < DBUS_NUM_MESSAGE_TYPES))
1366 XD_SIGNAL2 (build_string ("Invalid message type"), message_type);
1367 mtype = XFIXNAT (message_type);
1368
1369 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1370 || (mtype == DBUS_MESSAGE_TYPE_SIGNAL))
1371 {
1372 path = args[3];
1373 interface = args[4];
1374 member = args[5];
1375 if (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1376 handler = args[6];
1377 count = (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL) ? 7 : 6;
1378 }
1379 else if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1380 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1381 {
1382 serial = xd_extract_unsigned (args[3], TYPE_MAXIMUM (dbus_uint32_t));
1383 if (mtype == DBUS_MESSAGE_TYPE_ERROR)
1384 error_name = args[4];
1385 count = (mtype == DBUS_MESSAGE_TYPE_ERROR) ? 5 : 4;
1386 }
1387 else
1388 count = 3;
1389
1390
1391 XD_DBUS_VALIDATE_BUS_ADDRESS (bus);
1392 XD_DBUS_VALIDATE_BUS_NAME (service);
1393 if (nargs < count)
1394 xsignal2 (Qwrong_number_of_arguments,
1395 Qdbus_message_internal,
1396 make_fixnum (nargs));
1397
1398 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1399 || (mtype == DBUS_MESSAGE_TYPE_SIGNAL))
1400 {
1401 XD_DBUS_VALIDATE_PATH (path);
1402 XD_DBUS_VALIDATE_INTERFACE (interface);
1403 XD_DBUS_VALIDATE_MEMBER (member);
1404 if (!NILP (handler) && !FUNCTIONP (handler))
1405 wrong_type_argument (Qinvalid_function, handler);
1406 }
1407
1408
1409 switch (mtype)
1410 {
1411 case DBUS_MESSAGE_TYPE_METHOD_CALL:
1412 XD_DEBUG_MESSAGE ("%s %s %s %s %s %s %s",
1413 XD_MESSAGE_TYPE_TO_STRING (mtype),
1414 XD_OBJECT_TO_STRING (bus),
1415 XD_OBJECT_TO_STRING (service),
1416 XD_OBJECT_TO_STRING (path),
1417 XD_OBJECT_TO_STRING (interface),
1418 XD_OBJECT_TO_STRING (member),
1419 XD_OBJECT_TO_STRING (handler));
1420 break;
1421 case DBUS_MESSAGE_TYPE_SIGNAL:
1422 XD_DEBUG_MESSAGE ("%s %s %s %s %s %s",
1423 XD_MESSAGE_TYPE_TO_STRING (mtype),
1424 XD_OBJECT_TO_STRING (bus),
1425 XD_OBJECT_TO_STRING (service),
1426 XD_OBJECT_TO_STRING (path),
1427 XD_OBJECT_TO_STRING (interface),
1428 XD_OBJECT_TO_STRING (member));
1429 break;
1430 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
1431 ui_serial = serial;
1432 XD_DEBUG_MESSAGE ("%s %s %s %u",
1433 XD_MESSAGE_TYPE_TO_STRING (mtype),
1434 XD_OBJECT_TO_STRING (bus),
1435 XD_OBJECT_TO_STRING (service),
1436 ui_serial);
1437 break;
1438 case DBUS_MESSAGE_TYPE_ERROR:
1439 ui_serial = serial;
1440 XD_DEBUG_MESSAGE ("%s %s %s %u %s",
1441 XD_MESSAGE_TYPE_TO_STRING (mtype),
1442 XD_OBJECT_TO_STRING (bus),
1443 XD_OBJECT_TO_STRING (service),
1444 ui_serial,
1445 XD_OBJECT_TO_STRING (error_name));
1446 break;
1447 default:
1448 XD_DEBUG_MESSAGE ("%s %s %s",
1449 XD_MESSAGE_TYPE_TO_STRING (mtype),
1450 XD_OBJECT_TO_STRING (bus),
1451 XD_OBJECT_TO_STRING (service));
1452 }
1453
1454
1455 connection = xd_get_connection_address (bus);
1456
1457
1458
1459 dmessage = dbus_message_new
1460 ((mtype == DBUS_MESSAGE_TYPE_INVALID) ? DBUS_MESSAGE_TYPE_SIGNAL : mtype);
1461 if (dmessage == NULL)
1462 XD_SIGNAL1 (build_string ("Unable to create a new message"));
1463
1464 if ((STRINGP (service)) && (mtype != DBUS_MESSAGE_TYPE_INVALID))
1465 {
1466 if (mtype != DBUS_MESSAGE_TYPE_SIGNAL)
1467
1468 {
1469 if (!dbus_message_set_destination (dmessage, SSDATA (service)))
1470 XD_SIGNAL2 (build_string ("Unable to set the destination"),
1471 service);
1472 }
1473
1474 else
1475
1476 {
1477 Lisp_Object uname;
1478
1479
1480
1481
1482 if (dbus_bus_name_has_owner (connection, SSDATA (service), NULL))
1483 uname = call2 (intern ("dbus-get-name-owner"), bus, service);
1484 else
1485 uname = Qnil;
1486
1487 if (STRINGP (uname)
1488 && (strcmp (dbus_bus_get_unique_name (connection), SSDATA (uname))
1489 != 0)
1490 && (!dbus_message_set_destination (dmessage, SSDATA (service))))
1491 XD_SIGNAL2 (build_string ("Unable to set signal destination"),
1492 service);
1493 }
1494 }
1495
1496
1497 if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1498 || (mtype == DBUS_MESSAGE_TYPE_SIGNAL))
1499 {
1500 if ((!dbus_message_set_path (dmessage, SSDATA (path)))
1501 || (!dbus_message_set_interface (dmessage, SSDATA (interface)))
1502 || (!dbus_message_set_member (dmessage, SSDATA (member))))
1503 XD_SIGNAL1 (build_string ("Unable to set the message parameter"));
1504 }
1505
1506 else if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1507 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1508 {
1509 if (!dbus_message_set_reply_serial (dmessage, serial))
1510 XD_SIGNAL1 (build_string ("Unable to create a return message"));
1511
1512 if ((mtype == DBUS_MESSAGE_TYPE_ERROR)
1513 && (!dbus_message_set_error_name (dmessage, SSDATA (error_name))))
1514 XD_SIGNAL1 (build_string ("Unable to create an error message"));
1515 }
1516
1517
1518 if ((count + 2 <= nargs) && EQ (args[count], QCtimeout))
1519 {
1520 CHECK_FIXNAT (args[count+1]);
1521 timeout = min (XFIXNAT (args[count+1]), INT_MAX);
1522 count = count+2;
1523 }
1524
1525
1526 dbus_message_iter_init_append (dmessage, &iter);
1527
1528
1529 count0 = count - 1;
1530 for (; count < nargs; ++count)
1531 {
1532 dtype = XD_OBJECT_TO_DBUS_TYPE (args[count]);
1533 if (count + 1 < nargs && XD_DBUS_TYPE_P (args[count]))
1534 {
1535 XD_DEBUG_VALID_LISP_OBJECT_P (args[count]);
1536 XD_DEBUG_VALID_LISP_OBJECT_P (args[count+1]);
1537 XD_DEBUG_MESSAGE ("Parameter%"pD"d: %s Parameter%"pD"d: %s",
1538 count - count0,
1539 XD_OBJECT_TO_STRING (args[count]),
1540 count + 1 - count0,
1541 XD_OBJECT_TO_STRING (args[count+1]));
1542 ++count;
1543 }
1544 else
1545 {
1546 XD_DEBUG_VALID_LISP_OBJECT_P (args[count]);
1547 XD_DEBUG_MESSAGE ("Parameter%"pD"d: %s", count - count0,
1548 XD_OBJECT_TO_STRING (args[count]));
1549 }
1550
1551
1552
1553 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[count]);
1554
1555 xd_append_arg (dtype, args[count], &iter);
1556 }
1557
1558 if (mtype == DBUS_MESSAGE_TYPE_INVALID)
1559 result = Qt;
1560
1561 else if (!NILP (handler))
1562 {
1563
1564
1565 if (!dbus_connection_send_with_reply (connection, dmessage,
1566 NULL, timeout))
1567 XD_SIGNAL1 (build_string ("Cannot send message"));
1568
1569
1570 serial = dbus_message_get_serial (dmessage);
1571 result = list3 (QCserial, bus, INT_TO_INTEGER (serial));
1572
1573
1574 Fputhash (result, handler, Vdbus_registered_objects_table);
1575 }
1576 else
1577 {
1578
1579
1580 if (!dbus_connection_send (connection, dmessage, NULL))
1581 XD_SIGNAL1 (build_string ("Cannot send message"));
1582
1583 result = Qnil;
1584 }
1585
1586 if (mtype != DBUS_MESSAGE_TYPE_INVALID)
1587 XD_DEBUG_MESSAGE ("Message sent: %s", XD_OBJECT_TO_STRING (result));
1588
1589
1590 dbus_message_unref (dmessage);
1591
1592
1593 return result;
1594 }
1595
1596
1597
1598
1599 static void
1600 xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
1601 {
1602 Lisp_Object args, key, value;
1603 struct input_event event;
1604 DBusMessage *dmessage;
1605 DBusMessageIter iter;
1606 int dtype;
1607 int mtype;
1608 dbus_uint32_t serial;
1609 unsigned int ui_serial;
1610 const char *uname, *destination, *path, *interface, *member, *error_name;
1611
1612 dmessage = dbus_connection_pop_message (connection);
1613
1614
1615 if (dmessage == NULL)
1616 return;
1617
1618
1619 args = Qnil;
1620
1621
1622 if (dbus_message_iter_init (dmessage, &iter))
1623 {
1624 while ((dtype = dbus_message_iter_get_arg_type (&iter))
1625 != DBUS_TYPE_INVALID)
1626 {
1627 args = Fcons (xd_retrieve_arg (dtype, &iter), args);
1628 dbus_message_iter_next (&iter);
1629 }
1630
1631 args = Fnreverse (args);
1632 }
1633
1634
1635
1636 mtype = dbus_message_get_type (dmessage);
1637 ui_serial = serial =
1638 ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1639 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1640 ? dbus_message_get_reply_serial (dmessage)
1641 : dbus_message_get_serial (dmessage);
1642 uname = dbus_message_get_sender (dmessage);
1643 destination = dbus_message_get_destination (dmessage);
1644 path = dbus_message_get_path (dmessage);
1645 interface = dbus_message_get_interface (dmessage);
1646 member = dbus_message_get_member (dmessage);
1647 error_name = dbus_message_get_error_name (dmessage);
1648
1649 XD_DEBUG_MESSAGE ("Event received: %s %u %s %s %s %s %s %s",
1650 XD_MESSAGE_TYPE_TO_STRING (mtype),
1651 ui_serial, uname, destination, path, interface,
1652 mtype == DBUS_MESSAGE_TYPE_ERROR ? error_name : member,
1653 XD_OBJECT_TO_STRING (args));
1654
1655 if (mtype == DBUS_MESSAGE_TYPE_INVALID)
1656 goto cleanup;
1657
1658 else if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1659 || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1660 {
1661
1662 key = list3 (QCserial, bus, INT_TO_INTEGER (serial));
1663 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1664
1665
1666 if (NILP (value))
1667 goto monitor;
1668
1669
1670 Fremhash (key, Vdbus_registered_objects_table);
1671
1672
1673 EVENT_INIT (event);
1674 event.kind = DBUS_EVENT;
1675 event.frame_or_window = Qnil;
1676
1677 event.arg = Fcons (value, args);
1678 }
1679
1680 else
1681 {
1682
1683
1684 if ((interface == NULL) || (member == NULL))
1685 goto monitor;
1686
1687
1688 key = list4 (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL ? QCmethod : QCsignal,
1689 bus, build_string (interface), build_string (member));
1690 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1691
1692
1693 for (; !NILP (value); value = CDR_SAFE (value))
1694 {
1695 key = CAR_SAFE (value);
1696 Lisp_Object key_uname = CAR_SAFE (key);
1697
1698 if (uname && !NILP (key_uname)
1699 && strcmp (uname, SSDATA (key_uname)) != 0)
1700 continue;
1701 Lisp_Object key_service_etc = CDR_SAFE (key);
1702 Lisp_Object key_path_etc = CDR_SAFE (key_service_etc);
1703 Lisp_Object key_path = CAR_SAFE (key_path_etc);
1704 if (path && !NILP (key_path)
1705 && strcmp (path, SSDATA (key_path)) != 0)
1706 continue;
1707 Lisp_Object handler = CAR_SAFE (CDR_SAFE (key_path_etc));
1708 if (NILP (handler))
1709 continue;
1710
1711
1712 EVENT_INIT (event);
1713 event.kind = DBUS_EVENT;
1714 event.frame_or_window = Qnil;
1715 event.arg = Fcons (handler, args);
1716 break;
1717 }
1718
1719 if (NILP (value))
1720 goto monitor;
1721 }
1722
1723
1724
1725 event.arg
1726 = Fcons (mtype == DBUS_MESSAGE_TYPE_ERROR
1727 ? error_name == NULL ? Qnil : build_string (error_name)
1728 : member == NULL ? Qnil : build_string (member),
1729 event.arg);
1730 event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)),
1731 event.arg);
1732 event.arg = Fcons ((path == NULL ? Qnil : build_string (path)),
1733 event.arg);
1734 event.arg = Fcons ((destination == NULL ? Qnil : build_string (destination)),
1735 event.arg);
1736 event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)),
1737 event.arg);
1738 event.arg = Fcons (INT_TO_INTEGER (serial), event.arg);
1739 event.arg = Fcons (make_fixnum (mtype), event.arg);
1740
1741
1742 event.arg = Fcons (bus, event.arg);
1743
1744
1745 kbd_buffer_store_event (&event);
1746
1747 XD_DEBUG_MESSAGE ("Event stored: %s", XD_OBJECT_TO_STRING (event.arg));
1748
1749
1750 monitor:
1751
1752 key = list2 (QCmonitor, bus);
1753 value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1754
1755
1756 if (NILP (value))
1757 goto cleanup;
1758
1759
1760 EVENT_INIT (event);
1761 event.kind = DBUS_EVENT;
1762 event.frame_or_window = Qnil;
1763
1764
1765
1766 event.arg
1767 = Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (CAR_SAFE (value))))),
1768 args);
1769 event.arg
1770 = Fcons (mtype == DBUS_MESSAGE_TYPE_ERROR
1771 ? error_name == NULL ? Qnil : build_string (error_name)
1772 : member == NULL ? Qnil : build_string (member),
1773 event.arg);
1774 event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)),
1775 event.arg);
1776 event.arg = Fcons ((path == NULL ? Qnil : build_string (path)),
1777 event.arg);
1778 event.arg = Fcons ((destination == NULL ? Qnil : build_string (destination)),
1779 event.arg);
1780 event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)),
1781 event.arg);
1782 event.arg = Fcons (INT_TO_INTEGER (serial), event.arg);
1783 event.arg = Fcons (make_fixnum (mtype), event.arg);
1784
1785
1786 event.arg = Fcons (bus, event.arg);
1787
1788
1789 kbd_buffer_store_event (&event);
1790
1791 XD_DEBUG_MESSAGE ("Monitor event stored: %s", XD_OBJECT_TO_STRING (event.arg));
1792
1793
1794 cleanup:
1795 dbus_message_unref (dmessage);
1796 }
1797
1798
1799
1800
1801 static Lisp_Object
1802 xd_read_message (Lisp_Object bus)
1803 {
1804
1805 DBusConnection *connection = xd_get_connection_address (bus);
1806
1807
1808 dbus_connection_read_write (connection, 0);
1809
1810 while (dbus_connection_get_dispatch_status (connection)
1811 != DBUS_DISPATCH_COMPLETE)
1812 xd_read_message_1 (connection, bus);
1813 return Qnil;
1814 }
1815
1816
1817 static void
1818 xd_read_queued_messages (int fd, void *data)
1819 {
1820 Lisp_Object busp = xd_registered_buses;
1821 Lisp_Object bus = Qnil;
1822 Lisp_Object key;
1823
1824
1825 if (data != NULL)
1826 while (!NILP (busp))
1827 {
1828 key = CAR_SAFE (CAR_SAFE (busp));
1829 if ((XD_KEYWORDP (key) && XSYMBOL (key) == data)
1830 || (STRINGP (key) && XSTRING (key) == data))
1831 bus = key;
1832 busp = CDR_SAFE (busp);
1833 }
1834
1835 if (NILP (bus))
1836 return;
1837
1838
1839 xd_in_read_queued_messages = 1;
1840 internal_catch (Qdbus_error, xd_read_message, bus);
1841 xd_in_read_queued_messages = 0;
1842 }
1843
1844
1845 void
1846 init_dbusbind (void)
1847 {
1848
1849 xputenv ("DBUS_FATAL_WARNINGS=0");
1850 }
1851
1852 static void
1853 syms_of_dbusbind_for_pdumper (void)
1854 {
1855 xd_registered_buses = Qnil;
1856 }
1857
1858 void
1859 syms_of_dbusbind (void)
1860 {
1861 defsubr (&Sdbus__init_bus);
1862 defsubr (&Sdbus_get_unique_name);
1863
1864 DEFSYM (Qdbus_message_internal, "dbus-message-internal");
1865 defsubr (&Sdbus_message_internal);
1866
1867
1868 DEFSYM (Qdbus_error, "dbus-error");
1869 Fput (Qdbus_error, Qerror_conditions,
1870 list2 (Qdbus_error, Qerror));
1871 Fput (Qdbus_error, Qerror_message,
1872 build_pure_c_string ("D-Bus error"));
1873
1874
1875 DEFSYM (QCsystem, ":system");
1876 DEFSYM (QCsession, ":session");
1877 DEFSYM (QCsystem_private, ":system-private");
1878 DEFSYM (QCsession_private, ":session-private");
1879
1880
1881 DEFSYM (QCtimeout, ":timeout");
1882
1883
1884 DEFSYM (QCbyte, ":byte");
1885 DEFSYM (QCboolean, ":boolean");
1886 DEFSYM (QCint16, ":int16");
1887 DEFSYM (QCuint16, ":uint16");
1888 DEFSYM (QCint32, ":int32");
1889 DEFSYM (QCuint32, ":uint32");
1890 DEFSYM (QCint64, ":int64");
1891 DEFSYM (QCuint64, ":uint64");
1892 DEFSYM (QCdouble, ":double");
1893 DEFSYM (QCstring, ":string");
1894 DEFSYM (QCobject_path, ":object-path");
1895 DEFSYM (QCsignature, ":signature");
1896 #ifdef DBUS_TYPE_UNIX_FD
1897 DEFSYM (QCunix_fd, ":unix-fd");
1898 #endif
1899 DEFSYM (QCarray, ":array");
1900 DEFSYM (QCvariant, ":variant");
1901 DEFSYM (QCstruct, ":struct");
1902 DEFSYM (QCdict_entry, ":dict-entry");
1903
1904
1905
1906 DEFSYM (QCserial, ":serial");
1907 DEFSYM (QCmethod, ":method");
1908 DEFSYM (QCsignal, ":signal");
1909 DEFSYM (QCmonitor, ":monitor");
1910
1911 DEFVAR_LISP ("dbus-compiled-version",
1912 Vdbus_compiled_version,
1913 doc: );
1914 #ifdef DBUS_VERSION_STRING
1915 Vdbus_compiled_version = build_pure_c_string (DBUS_VERSION_STRING);
1916 #else
1917 Vdbus_compiled_version = Qnil;
1918 #endif
1919
1920 DEFVAR_LISP ("dbus-runtime-version",
1921 Vdbus_runtime_version,
1922 doc: );
1923 {
1924 #ifdef DBUS_VERSION
1925 int major, minor, micro;
1926 char s[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
1927 dbus_get_version (&major, &minor, µ);
1928 Vdbus_runtime_version
1929 = make_formatted_string (s, "%d.%d.%d", major, minor, micro);
1930 #else
1931 Vdbus_runtime_version = Qnil;
1932 #endif
1933 }
1934
1935 DEFVAR_LISP ("dbus-message-type-invalid",
1936 Vdbus_message_type_invalid,
1937 doc: );
1938 Vdbus_message_type_invalid = make_fixnum (DBUS_MESSAGE_TYPE_INVALID);
1939
1940 DEFVAR_LISP ("dbus-message-type-method-call",
1941 Vdbus_message_type_method_call,
1942 doc: );
1943 Vdbus_message_type_method_call = make_fixnum (DBUS_MESSAGE_TYPE_METHOD_CALL);
1944
1945 DEFVAR_LISP ("dbus-message-type-method-return",
1946 Vdbus_message_type_method_return,
1947 doc: );
1948 Vdbus_message_type_method_return
1949 = make_fixnum (DBUS_MESSAGE_TYPE_METHOD_RETURN);
1950
1951 DEFVAR_LISP ("dbus-message-type-error",
1952 Vdbus_message_type_error,
1953 doc: );
1954 Vdbus_message_type_error = make_fixnum (DBUS_MESSAGE_TYPE_ERROR);
1955
1956 DEFVAR_LISP ("dbus-message-type-signal",
1957 Vdbus_message_type_signal,
1958 doc: );
1959 Vdbus_message_type_signal = make_fixnum (DBUS_MESSAGE_TYPE_SIGNAL);
1960
1961 DEFVAR_LISP ("dbus-registered-objects-table",
1962 Vdbus_registered_objects_table,
1963 doc:
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999 );
2000 Vdbus_registered_objects_table = CALLN (Fmake_hash_table, QCtest, Qequal);
2001
2002 DEFVAR_LISP ("dbus-debug", Vdbus_debug,
2003 doc: );
2004 #ifdef DBUS_DEBUG
2005 Vdbus_debug = Qt;
2006
2007
2008
2009 #else
2010 Vdbus_debug = Qnil;
2011 #endif
2012
2013
2014 pdumper_do_now_and_after_load (syms_of_dbusbind_for_pdumper);
2015 staticpro (&xd_registered_buses);
2016
2017 Fprovide (intern_c_string ("dbusbind"), Qnil);
2018 }
2019
2020 #endif