comparison src/dbusbind.c @ 87361:0b387233ea86

* dbusbind.c (XD_BASIC_DBUS_TYPE, XD_DBUS_TYPE_P, XD_NEXT_VALUE): New macros. (XD_SYMBOL_TO_DBUS_TYPE): Renamed from XD_LISP_SYMBOL_TO_DBUS_TYPE. (XD_OBJECT_TO_DBUS_TYPE): Renamed from XD_LISP_OBJECT_TO_DBUS_TYPE. Simplify. (xd_signature): New function. (xd_append_arg): Compute also signatures. Major rewrite. (xd_retrieve_arg): Make debug messages friendly. (Fdbus_call_method, Fdbus_send_signal): Extend docstring. Check for signatures of arguments.
author Michael Albinus <michael.albinus@gmx.de>
date Fri, 21 Dec 2007 22:01:43 +0000
parents 02e327d7d839
children 28bc3dd3635f
comparison
equal deleted inserted replaced
87360:c7024d3b9ea3 87361:0b387233ea86
101 message ("%s: %s", __func__, s); \ 101 message ("%s: %s", __func__, s); \
102 } 102 }
103 #define XD_DEBUG_VALID_LISP_OBJECT_P(object) 103 #define XD_DEBUG_VALID_LISP_OBJECT_P(object)
104 #endif 104 #endif
105 105
106 /* Check whether TYPE is a basic DBusType. */
107 #define XD_BASIC_DBUS_TYPE(type) \
108 ((type == DBUS_TYPE_BYTE) \
109 || (type == DBUS_TYPE_BOOLEAN) \
110 || (type == DBUS_TYPE_INT16) \
111 || (type == DBUS_TYPE_UINT16) \
112 || (type == DBUS_TYPE_INT32) \
113 || (type == DBUS_TYPE_UINT32) \
114 || (type == DBUS_TYPE_INT64) \
115 || (type == DBUS_TYPE_UINT64) \
116 || (type == DBUS_TYPE_DOUBLE) \
117 || (type == DBUS_TYPE_STRING) \
118 || (type == DBUS_TYPE_OBJECT_PATH) \
119 || (type == DBUS_TYPE_SIGNATURE))
120
106 /* Determine the DBusType of a given Lisp symbol. OBJECT must be one 121 /* Determine the DBusType of a given Lisp symbol. OBJECT must be one
107 of the predefined D-Bus type symbols. */ 122 of the predefined D-Bus type symbols. */
108 #define XD_LISP_SYMBOL_TO_DBUS_TYPE(object) \ 123 #define XD_SYMBOL_TO_DBUS_TYPE(object) \
109 (EQ (object, QCdbus_type_byte)) ? DBUS_TYPE_BYTE \ 124 ((EQ (object, QCdbus_type_byte)) ? DBUS_TYPE_BYTE \
110 : (EQ (object, QCdbus_type_boolean)) ? DBUS_TYPE_BOOLEAN \ 125 : (EQ (object, QCdbus_type_boolean)) ? DBUS_TYPE_BOOLEAN \
111 : (EQ (object, QCdbus_type_int16)) ? DBUS_TYPE_INT16 \ 126 : (EQ (object, QCdbus_type_int16)) ? DBUS_TYPE_INT16 \
112 : (EQ (object, QCdbus_type_uint16)) ? DBUS_TYPE_UINT16 \ 127 : (EQ (object, QCdbus_type_uint16)) ? DBUS_TYPE_UINT16 \
113 : (EQ (object, QCdbus_type_int32)) ? DBUS_TYPE_INT32 \ 128 : (EQ (object, QCdbus_type_int32)) ? DBUS_TYPE_INT32 \
114 : (EQ (object, QCdbus_type_uint32)) ? DBUS_TYPE_UINT32 \ 129 : (EQ (object, QCdbus_type_uint32)) ? DBUS_TYPE_UINT32 \
115 : (EQ (object, QCdbus_type_int64)) ? DBUS_TYPE_INT64 \ 130 : (EQ (object, QCdbus_type_int64)) ? DBUS_TYPE_INT64 \
116 : (EQ (object, QCdbus_type_uint64)) ? DBUS_TYPE_UINT64 \ 131 : (EQ (object, QCdbus_type_uint64)) ? DBUS_TYPE_UINT64 \
117 : (EQ (object, QCdbus_type_double)) ? DBUS_TYPE_DOUBLE \ 132 : (EQ (object, QCdbus_type_double)) ? DBUS_TYPE_DOUBLE \
118 : (EQ (object, QCdbus_type_string)) ? DBUS_TYPE_STRING \ 133 : (EQ (object, QCdbus_type_string)) ? DBUS_TYPE_STRING \
119 : (EQ (object, QCdbus_type_object_path)) ? DBUS_TYPE_OBJECT_PATH \ 134 : (EQ (object, QCdbus_type_object_path)) ? DBUS_TYPE_OBJECT_PATH \
120 : (EQ (object, QCdbus_type_signature)) ? DBUS_TYPE_SIGNATURE \ 135 : (EQ (object, QCdbus_type_signature)) ? DBUS_TYPE_SIGNATURE \
121 : (EQ (object, QCdbus_type_array)) ? DBUS_TYPE_ARRAY \ 136 : (EQ (object, QCdbus_type_array)) ? DBUS_TYPE_ARRAY \
122 : (EQ (object, QCdbus_type_variant)) ? DBUS_TYPE_VARIANT \ 137 : (EQ (object, QCdbus_type_variant)) ? DBUS_TYPE_VARIANT \
123 : (EQ (object, QCdbus_type_struct)) ? DBUS_TYPE_STRUCT \ 138 : (EQ (object, QCdbus_type_struct)) ? DBUS_TYPE_STRUCT \
124 : (EQ (object, QCdbus_type_dict_entry)) ? DBUS_TYPE_DICT_ENTRY \ 139 : (EQ (object, QCdbus_type_dict_entry)) ? DBUS_TYPE_DICT_ENTRY \
125 : DBUS_TYPE_INVALID 140 : DBUS_TYPE_INVALID)
141
142 /* Check whether a Lisp symbol is a predefined D-Bus type symbol. */
143 #define XD_DBUS_TYPE_P(object) \
144 (SYMBOLP (object) && ((XD_SYMBOL_TO_DBUS_TYPE (object) != DBUS_TYPE_INVALID)))
126 145
127 /* Determine the DBusType of a given Lisp OBJECT. It is used to 146 /* Determine the DBusType of a given Lisp OBJECT. It is used to
128 convert Lisp objects, being arguments of `dbus-call-method' or 147 convert Lisp objects, being arguments of `dbus-call-method' or
129 `dbus-send-signal', into corresponding C values appended as 148 `dbus-send-signal', into corresponding C values appended as
130 arguments to a D-Bus message. */ 149 arguments to a D-Bus message. */
131 #define XD_LISP_OBJECT_TO_DBUS_TYPE(object) \ 150 #define XD_OBJECT_TO_DBUS_TYPE(object) \
132 (EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN \ 151 ((EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN \
133 : (SYMBOLP (object)) ? XD_LISP_SYMBOL_TO_DBUS_TYPE (object) \ 152 : (NATNUMP (object)) ? DBUS_TYPE_UINT32 \
134 : (CONSP (object)) ? ((SYMBOLP (XCAR (object)) \ 153 : (INTEGERP (object)) ? DBUS_TYPE_INT32 \
135 && !EQ (XCAR (object), Qt) \ 154 : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \
136 && !EQ (XCAR (object), Qnil)) \ 155 : (STRINGP (object)) ? DBUS_TYPE_STRING \
137 ? XD_LISP_SYMBOL_TO_DBUS_TYPE (XCAR (object)) \ 156 : (XD_DBUS_TYPE_P (object)) ? XD_SYMBOL_TO_DBUS_TYPE (object) \
138 : DBUS_TYPE_ARRAY) \ 157 : (CONSP (object)) ? ((XD_DBUS_TYPE_P (XCAR (object))) \
139 : (NATNUMP (object)) ? DBUS_TYPE_UINT32 \ 158 ? XD_SYMBOL_TO_DBUS_TYPE (XCAR (object)) \
140 : (INTEGERP (object)) ? DBUS_TYPE_INT32 \ 159 : DBUS_TYPE_ARRAY) \
141 : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \ 160 : DBUS_TYPE_INVALID)
142 : (STRINGP (object)) ? DBUS_TYPE_STRING \ 161
143 : DBUS_TYPE_INVALID 162 /* Return a list pointer which does not have a Lisp symbol as car. */
163 #define XD_NEXT_VALUE(object) \
164 ((XD_DBUS_TYPE_P (XCAR (object))) ? XCDR (object) : object)
165
166 /* Compute SIGNATURE of OBJECT. It must have a form that it can be
167 used in dbus_message_iter_open_container. DTYPE is the DBusType
168 the object is related to. It is passed as argument, because it
169 cannot be detected in basic type objects, when they are preceded by
170 a type symbol. PARENT_TYPE is the DBusType of a container this
171 signature is embedded, or DBUS_TYPE_INVALID. It is needed for the
172 check that DBUS_TYPE_DICT_ENTRY occurs only as array element. */
173 void
174 xd_signature(signature, dtype, parent_type, object)
175 char *signature;
176 unsigned int dtype, parent_type;
177 Lisp_Object object;
178 {
179 unsigned int subtype;
180 Lisp_Object elt;
181 char x[DBUS_MAXIMUM_SIGNATURE_LENGTH];
182
183 elt = object;
184
185 switch (dtype)
186 {
187 case DBUS_TYPE_BYTE:
188 case DBUS_TYPE_UINT16:
189 case DBUS_TYPE_UINT32:
190 case DBUS_TYPE_UINT64:
191 CHECK_NATNUM (object);
192 sprintf (signature, "%c", dtype);
193 break;
194
195 case DBUS_TYPE_BOOLEAN:
196 if (!EQ (object, Qt) && !EQ (object, Qnil))
197 wrong_type_argument (intern ("booleanp"), object);
198 sprintf (signature, "%c", dtype);
199 break;
200
201 case DBUS_TYPE_INT16:
202 case DBUS_TYPE_INT32:
203 case DBUS_TYPE_INT64:
204 CHECK_NUMBER (object);
205 sprintf (signature, "%c", dtype);
206 break;
207
208 case DBUS_TYPE_DOUBLE:
209 CHECK_FLOAT (object);
210 sprintf (signature, "%c", dtype);
211 break;
212
213 case DBUS_TYPE_STRING:
214 case DBUS_TYPE_OBJECT_PATH:
215 case DBUS_TYPE_SIGNATURE:
216 CHECK_STRING (object);
217 sprintf (signature, "%c", dtype);
218 break;
219
220 case DBUS_TYPE_ARRAY:
221 /* Check that all elements have the same D-Bus type. For
222 complex element types, we just check the container type, not
223 the whole element's signature. */
224 CHECK_CONS (object);
225
226 if (EQ (QCdbus_type_array, XCAR (elt))) /* Type symbol is optional. */
227 elt = XD_NEXT_VALUE (elt);
228 subtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (elt));
229 xd_signature (x, subtype, dtype, XCAR (XD_NEXT_VALUE (elt)));
230
231 while (!NILP (elt))
232 {
233 if (subtype != XD_OBJECT_TO_DBUS_TYPE (XCAR (elt)))
234 wrong_type_argument (intern ("D-Bus"), XCAR (elt));
235 elt = XCDR (XD_NEXT_VALUE (elt));
236 }
237
238 sprintf (signature, "%c%s", dtype, x);
239 break;
240
241 case DBUS_TYPE_VARIANT:
242 /* Check that there is exactly one element. */
243 CHECK_CONS (object);
244
245 elt = XD_NEXT_VALUE (elt);
246 subtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (elt));
247 xd_signature (x, subtype, dtype, XCAR (XD_NEXT_VALUE (elt)));
248
249 if (!NILP (XCDR (XD_NEXT_VALUE (elt))))
250 wrong_type_argument (intern ("D-Bus"),
251 XCAR (XCDR (XD_NEXT_VALUE (elt))));
252
253 sprintf (signature, "%c%s", dtype, x);
254 break;
255
256 case DBUS_TYPE_STRUCT:
257 /* A struct might contain any number of objects with different
258 types. No further check needed. */
259 CHECK_CONS (object);
260
261 elt = XD_NEXT_VALUE (elt);
262
263 /* Compose the signature from the elements. It is enclosed by
264 parentheses. */
265 sprintf (signature, "%c", DBUS_STRUCT_BEGIN_CHAR );
266 while (!NILP (elt))
267 {
268 subtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (elt));
269 xd_signature (x, subtype, dtype, XCAR (XD_NEXT_VALUE (elt)));
270 strcat (signature, x);
271 elt = XCDR (XD_NEXT_VALUE (elt));
272 }
273 sprintf (signature, "%s%c", signature, DBUS_STRUCT_END_CHAR);
274 break;
275
276 case DBUS_TYPE_DICT_ENTRY:
277 /* Check that there are exactly two elements, and the first one
278 is of basic type. It must also be an element of an
279 array. */
280 CHECK_CONS (object);
281
282 if (parent_type != DBUS_TYPE_ARRAY)
283 wrong_type_argument (intern ("D-Bus"), object);
284
285 /* Compose the signature from the elements. It is enclosed by
286 curly braces. */
287 sprintf (signature, "%c", DBUS_DICT_ENTRY_BEGIN_CHAR);
288
289 /* First element. */
290 elt = XD_NEXT_VALUE (elt);
291 subtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (elt));
292 xd_signature (x, subtype, dtype, XCAR (XD_NEXT_VALUE (elt)));
293 strcat (signature, x);
294
295 if (!XD_BASIC_DBUS_TYPE (subtype))
296 wrong_type_argument (intern ("D-Bus"), XCAR (XD_NEXT_VALUE (elt)));
297
298 /* Second element. */
299 elt = XCDR (XD_NEXT_VALUE (elt));
300 subtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (elt));
301 xd_signature (x, subtype, dtype, XCAR (XD_NEXT_VALUE (elt)));
302 strcat (signature, x);
303
304 if (!NILP (XCDR (XD_NEXT_VALUE (elt))))
305 wrong_type_argument (intern ("D-Bus"),
306 XCAR (XCDR (XD_NEXT_VALUE (elt))));
307
308 /* Closing signature. */
309 sprintf (signature, "%s%c", signature, DBUS_DICT_ENTRY_END_CHAR);
310 break;
311
312 default:
313 wrong_type_argument (intern ("D-Bus"), object);
314 }
315
316 XD_DEBUG_MESSAGE ("%s", signature);
317 }
144 318
145 /* Append C value, extracted from Lisp OBJECT, to iteration ITER. 319 /* Append C value, extracted from Lisp OBJECT, to iteration ITER.
146 DTYPE must be a valid DBusType. It is used to convert Lisp 320 DTYPE must be a valid DBusType. It is used to convert Lisp
147 objects, being arguments of `dbus-call-method' or 321 objects, being arguments of `dbus-call-method' or
148 `dbus-send-signal', into corresponding C values appended as 322 `dbus-send-signal', into corresponding C values appended as
149 arguments to a D-Bus message. */ 323 arguments to a D-Bus message. */
150 void 324 void
151 xd_append_arg (dtype, object, iter) 325 xd_append_arg (dtype, object, iter)
152 unsigned int dtype; 326 unsigned int dtype;
327 Lisp_Object object;
153 DBusMessageIter *iter; 328 DBusMessageIter *iter;
154 Lisp_Object object;
155 { 329 {
330 Lisp_Object elt;
331 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
332 DBusMessageIter subiter;
156 char *value; 333 char *value;
157 334
158 /* Check type of object. If this has been detected implicitely, it 335 XD_DEBUG_MESSAGE ("%c %s", dtype, SDATA (format2 ("%s", object, Qnil)));
159 is OK already, but there might be cases the type symbol and the 336
160 corresponding object do'nt match. */ 337 if (XD_BASIC_DBUS_TYPE (dtype))
161 switch (dtype) 338 {
162 { 339 switch (dtype)
163 case DBUS_TYPE_BYTE: 340 {
164 case DBUS_TYPE_UINT16: 341 case DBUS_TYPE_BYTE:
165 case DBUS_TYPE_UINT32: 342 XD_DEBUG_MESSAGE ("%c %u", dtype, XUINT (object));
166 case DBUS_TYPE_UINT64: 343 value = (unsigned char *) XUINT (object);
167 CHECK_NATNUM (object); 344 break;
168 break; 345
169 case DBUS_TYPE_BOOLEAN: 346 case DBUS_TYPE_BOOLEAN:
170 if (!EQ (object, Qt) && !EQ (object, Qnil)) 347 XD_DEBUG_MESSAGE ("%c %s", dtype, (NILP (object)) ? "false" : "true");
171 wrong_type_argument (intern ("booleanp"), object); 348 value = (NILP (object))
172 break; 349 ? (unsigned char *) FALSE : (unsigned char *) TRUE;
173 case DBUS_TYPE_INT16: 350 break;
174 case DBUS_TYPE_INT32: 351
175 case DBUS_TYPE_INT64: 352 case DBUS_TYPE_INT16:
176 CHECK_NUMBER (object); 353 XD_DEBUG_MESSAGE ("%c %d", dtype, XINT (object));
177 break; 354 value = (char *) (dbus_int16_t *) XINT (object);
178 case DBUS_TYPE_DOUBLE: 355 break;
179 CHECK_FLOAT (object); 356
180 break; 357 case DBUS_TYPE_UINT16:
181 case DBUS_TYPE_STRING: 358 XD_DEBUG_MESSAGE ("%c %u", dtype, XUINT (object));
182 case DBUS_TYPE_OBJECT_PATH: 359 value = (char *) (dbus_uint16_t *) XUINT (object);
183 case DBUS_TYPE_SIGNATURE: 360 break;
184 CHECK_STRING (object); 361
185 break; 362 case DBUS_TYPE_INT32:
186 case DBUS_TYPE_ARRAY: 363 XD_DEBUG_MESSAGE ("%c %d", dtype, XINT (object));
187 CHECK_CONS (object); 364 value = (char *) (dbus_int32_t *) XINT (object);
188 /* ToDo: Check that all list elements have the same type. */ 365 break;
189 break; 366
190 case DBUS_TYPE_VARIANT: 367 case DBUS_TYPE_UINT32:
191 CHECK_CONS (object); 368 XD_DEBUG_MESSAGE ("%c %u", dtype, XUINT (object));
192 /* ToDo: Check that there is exactly one element of basic type. */ 369 value = (char *) (dbus_uint32_t *) XUINT (object);
193 break; 370 break;
194 case DBUS_TYPE_STRUCT: 371
195 CHECK_CONS (object); 372 case DBUS_TYPE_INT64:
196 break; 373 XD_DEBUG_MESSAGE ("%c %d", dtype, XINT (object));
197 case DBUS_TYPE_DICT_ENTRY: 374 value = (char *) (dbus_int64_t *) XINT (object);
198 /* ToDo: Check that there are exactly two elements, and the 375 break;
199 first one is of basic type. */ 376
200 CHECK_CONS (object); 377 case DBUS_TYPE_UINT64:
201 break; 378 XD_DEBUG_MESSAGE ("%c %u", dtype, XUINT (object));
202 default: 379 value = (char *) (dbus_int64_t *) XUINT (object);
203 xsignal1 (Qdbus_error, build_string ("Unknown D-Bus type")); 380 break;
204 } 381
205 382 case DBUS_TYPE_DOUBLE:
206 if (CONSP (object)) 383 XD_DEBUG_MESSAGE ("%c %f", dtype, XFLOAT (object));
207 384 value = (char *) (float *) XFLOAT (object);
208 /* Compound types. */ 385 break;
209 { 386
210 DBusMessageIter subiter; 387 case DBUS_TYPE_STRING:
211 char subtype; 388 case DBUS_TYPE_OBJECT_PATH:
212 389 case DBUS_TYPE_SIGNATURE:
213 if (SYMBOLP (XCAR (object)) 390 XD_DEBUG_MESSAGE ("%c %s", dtype, SDATA (object));
214 && (strncmp (SDATA (XSYMBOL (XCAR (object))->xname), ":", 1) == 0)) 391 value = SDATA (object);
215 object = XCDR (object); 392 break;
393 }
394
395 if (!dbus_message_iter_append_basic (iter, dtype, &value))
396 xsignal2 (Qdbus_error,
397 build_string ("Unable to append argument"), object);
398 }
399
400 else /* Compound types. */
401 {
402
403 /* All compound types except array have a type symbol. For
404 array, it is optional. Skip it. */
405 if (!XD_BASIC_DBUS_TYPE (XD_OBJECT_TO_DBUS_TYPE (XCAR (object))))
406 object = XD_NEXT_VALUE (object);
216 407
217 /* Open new subiteration. */ 408 /* Open new subiteration. */
218 switch (dtype) 409 switch (dtype)
219 { 410 {
220 case DBUS_TYPE_ARRAY: 411 case DBUS_TYPE_ARRAY:
221 case DBUS_TYPE_VARIANT: 412 case DBUS_TYPE_VARIANT:
222 subtype = (char) XD_LISP_OBJECT_TO_DBUS_TYPE (XCAR (object)); 413 /* A variant has just one element. An array has elements of
223 dbus_message_iter_open_container (iter, dtype, &subtype, &subiter); 414 the same type. Both have been checked already, it is
415 sufficient to retrieve just the signature of the first
416 element. */
417 xd_signature (signature, XD_OBJECT_TO_DBUS_TYPE (XCAR (object)),
418 dtype, XCAR (XD_NEXT_VALUE (object)));
419 XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature,
420 SDATA (format2 ("%s", object, Qnil)));
421 if (!dbus_message_iter_open_container (iter, dtype,
422 signature, &subiter))
423 xsignal3 (Qdbus_error,
424 build_string ("Cannot open container"),
425 make_number (dtype), build_string (signature));
224 break; 426 break;
427
225 case DBUS_TYPE_STRUCT: 428 case DBUS_TYPE_STRUCT:
226 case DBUS_TYPE_DICT_ENTRY: 429 case DBUS_TYPE_DICT_ENTRY:
227 dbus_message_iter_open_container (iter, dtype, NULL, &subiter); 430 XD_DEBUG_MESSAGE ("%c %s", dtype,
431 SDATA (format2 ("%s", object, Qnil)));
432 if (!dbus_message_iter_open_container (iter, dtype, NULL, &subiter))
433 xsignal2 (Qdbus_error,
434 build_string ("Cannot open container"),
435 make_number (dtype));
436 break;
228 } 437 }
229 438
230 /* Loop over list elements. */ 439 /* Loop over list elements. */
231 while (!NILP (object)) 440 while (!NILP (object))
232 { 441 {
233 dtype = XD_LISP_OBJECT_TO_DBUS_TYPE (XCAR (object)); 442 dtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (object));
234 if (dtype == DBUS_TYPE_INVALID) 443 object = XD_NEXT_VALUE (object);
235 xsignal2 (Qdbus_error,
236 build_string ("Not a valid argument"), XCAR (object));
237
238 if (SYMBOLP (XCAR (object))
239 && (strncmp (SDATA (XSYMBOL (XCAR (object))->xname), ":", 1)
240 == 0))
241 object = XCDR (object);
242 444
243 xd_append_arg (dtype, XCAR (object), &subiter); 445 xd_append_arg (dtype, XCAR (object), &subiter);
244 446
245 object = XCDR (object); 447 object = XCDR (object);
246 } 448 }
247 449
248 dbus_message_iter_close_container (iter, &subiter); 450 if (!dbus_message_iter_close_container (iter, &subiter))
249 }
250
251 else
252
253 /* Basic type. */
254 {
255 switch (dtype)
256 {
257 case DBUS_TYPE_BYTE:
258 XD_DEBUG_MESSAGE ("%d %u", dtype, XUINT (object));
259 value = (unsigned char *) XUINT (object);
260 break;
261 case DBUS_TYPE_BOOLEAN:
262 XD_DEBUG_MESSAGE ("%d %s", dtype, (NILP (object)) ? "false" : "true");
263 value = (NILP (object))
264 ? (unsigned char *) FALSE : (unsigned char *) TRUE;
265 break;
266 case DBUS_TYPE_INT16:
267 XD_DEBUG_MESSAGE ("%d %d", dtype, XINT (object));
268 value = (char *) (dbus_int16_t *) XINT (object);
269 break;
270 case DBUS_TYPE_UINT16:
271 XD_DEBUG_MESSAGE ("%d %u", dtype, XUINT (object));
272 value = (char *) (dbus_uint16_t *) XUINT (object);
273 break;
274 case DBUS_TYPE_INT32:
275 XD_DEBUG_MESSAGE ("%d %d", dtype, XINT (object));
276 value = (char *) (dbus_int32_t *) XINT (object);
277 break;
278 case DBUS_TYPE_UINT32:
279 XD_DEBUG_MESSAGE ("%d %u", dtype, XUINT (object));
280 value = (char *) (dbus_uint32_t *) XUINT (object);
281 break;
282 case DBUS_TYPE_INT64:
283 XD_DEBUG_MESSAGE ("%d %d", dtype, XINT (object));
284 value = (char *) (dbus_int64_t *) XINT (object);
285 break;
286 case DBUS_TYPE_UINT64:
287 XD_DEBUG_MESSAGE ("%d %u", dtype, XUINT (object));
288 value = (char *) (dbus_int64_t *) XUINT (object);
289 break;
290 case DBUS_TYPE_DOUBLE:
291 XD_DEBUG_MESSAGE ("%d %f", dtype, XFLOAT (object));
292 value = (char *) (float *) XFLOAT (object);
293 break;
294 case DBUS_TYPE_STRING:
295 case DBUS_TYPE_OBJECT_PATH:
296 case DBUS_TYPE_SIGNATURE:
297 XD_DEBUG_MESSAGE ("%d %s", dtype, SDATA (object));
298 value = SDATA (object);
299 break;
300 }
301 if (!dbus_message_iter_append_basic (iter, dtype, &value))
302 xsignal2 (Qdbus_error, 451 xsignal2 (Qdbus_error,
303 build_string ("Unable to append argument"), object); 452 build_string ("Cannot close container"),
453 make_number (dtype));
304 } 454 }
305 } 455 }
306 456
307 /* Retrieve C value from a DBusMessageIter structure ITER, and return 457 /* Retrieve C value from a DBusMessageIter structure ITER, and return
308 a converted Lisp object. The type DTYPE of the argument of the 458 a converted Lisp object. The type DTYPE of the argument of the
318 { 468 {
319 case DBUS_TYPE_BOOLEAN: 469 case DBUS_TYPE_BOOLEAN:
320 { 470 {
321 dbus_bool_t val; 471 dbus_bool_t val;
322 dbus_message_iter_get_basic (iter, &val); 472 dbus_message_iter_get_basic (iter, &val);
323 XD_DEBUG_MESSAGE ("%d %s", dtype, (val == FALSE) ? "false" : "true"); 473 XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
324 return (val == FALSE) ? Qnil : Qt; 474 return (val == FALSE) ? Qnil : Qt;
325 } 475 }
476
326 case DBUS_TYPE_INT32: 477 case DBUS_TYPE_INT32:
327 case DBUS_TYPE_UINT32: 478 case DBUS_TYPE_UINT32:
328 { 479 {
329 dbus_uint32_t val; 480 dbus_uint32_t val;
330 dbus_message_iter_get_basic (iter, &val); 481 dbus_message_iter_get_basic (iter, &val);
331 XD_DEBUG_MESSAGE ("%d %d", dtype, val); 482 XD_DEBUG_MESSAGE ("%c %d", dtype, val);
332 return make_number (val); 483 return make_number (val);
333 } 484 }
485
334 case DBUS_TYPE_STRING: 486 case DBUS_TYPE_STRING:
335 case DBUS_TYPE_OBJECT_PATH: 487 case DBUS_TYPE_OBJECT_PATH:
336 { 488 {
337 char *val; 489 char *val;
338 dbus_message_iter_get_basic (iter, &val); 490 dbus_message_iter_get_basic (iter, &val);
339 XD_DEBUG_MESSAGE ("%d %s", dtype, val); 491 XD_DEBUG_MESSAGE ("%c %s", dtype, val);
340 return build_string (val); 492 return build_string (val);
341 } 493 }
494
342 case DBUS_TYPE_ARRAY: 495 case DBUS_TYPE_ARRAY:
343 case DBUS_TYPE_VARIANT: 496 case DBUS_TYPE_VARIANT:
344 case DBUS_TYPE_STRUCT: 497 case DBUS_TYPE_STRUCT:
345 case DBUS_TYPE_DICT_ENTRY: 498 case DBUS_TYPE_DICT_ENTRY:
346 { 499 {
357 result = Fcons (xd_retrieve_arg (subtype, &subiter), result); 510 result = Fcons (xd_retrieve_arg (subtype, &subiter), result);
358 dbus_message_iter_next (&subiter); 511 dbus_message_iter_next (&subiter);
359 } 512 }
360 RETURN_UNGCPRO (Fnreverse (result)); 513 RETURN_UNGCPRO (Fnreverse (result));
361 } 514 }
515
362 default: 516 default:
363 XD_DEBUG_MESSAGE ("DBusType %d not supported", dtype); 517 XD_DEBUG_MESSAGE ("DBusType '%c' not supported", dtype);
364 return Qnil; 518 return Qnil;
365 } 519 }
366 } 520 }
367 521
368 522
437 t and nil => DBUS_TYPE_BOOLEAN 591 t and nil => DBUS_TYPE_BOOLEAN
438 number => DBUS_TYPE_UINT32 592 number => DBUS_TYPE_UINT32
439 integer => DBUS_TYPE_INT32 593 integer => DBUS_TYPE_INT32
440 float => DBUS_TYPE_DOUBLE 594 float => DBUS_TYPE_DOUBLE
441 string => DBUS_TYPE_STRING 595 string => DBUS_TYPE_STRING
442 596 list => DBUS_TYPE_ARRAY
443 Other Lisp objects are not supported as input arguments of METHOD. 597
598 All arguments can be preceded by a type symbol. For details about
599 type symbols, see Info node `(dbus)Type Conversion'.
444 600
445 `dbus-call-method' returns the resulting values of METHOD as a list of 601 `dbus-call-method' returns the resulting values of METHOD as a list of
446 Lisp objects. The type conversion happens the other direction as for 602 Lisp objects. The type conversion happens the other direction as for
447 input arguments. Additionally to the types supported for input 603 input arguments. It follows the mapping rules:
448 arguments, the D-Bus compound types DBUS_TYPE_ARRAY, DBUS_TYPE_VARIANT, 604
449 DBUS_TYPE_STRUCT and DBUS_TYPE_DICT_ENTRY are accepted. All of them 605 DBUS_TYPE_BOOLEAN => t or nil
450 are converted into a list of Lisp objects which correspond to the 606 DBUS_TYPE_BYTE => number
451 elements of the D-Bus container. Example: 607 DBUS_TYPE_UINT16 => number
608 DBUS_TYPE_INT16 => integer
609 DBUS_TYPE_UINT32 => number
610 DBUS_TYPE_INT32 => integer
611 DBUS_TYPE_UINT64 => number
612 DBUS_TYPE_INT64 => integer
613 DBUS_TYPE_DOUBLE => float
614 DBUS_TYPE_STRING => string
615 DBUS_TYPE_OBJECT_PATH => string
616 DBUS_TYPE_SIGNATURE => string
617 DBUS_TYPE_ARRAY => list
618 DBUS_TYPE_VARIANT => list
619 DBUS_TYPE_STRUCT => list
620 DBUS_TYPE_DICT_ENTRY => list
621
622 Example:
452 623
453 \(dbus-call-method 624 \(dbus-call-method
454 :session "org.gnome.seahorse" "/org/gnome/seahorse/keys/openpgp" 625 :session "org.gnome.seahorse" "/org/gnome/seahorse/keys/openpgp"
455 "org.gnome.seahorse.Keys" "GetKeyField" 626 "org.gnome.seahorse.Keys" "GetKeyField"
456 "openpgp:657984B8C7A966DD" "simple-name") 627 "openpgp:657984B8C7A966DD" "simple-name")
480 DBusMessage *reply; 651 DBusMessage *reply;
481 DBusMessageIter iter; 652 DBusMessageIter iter;
482 DBusError derror; 653 DBusError derror;
483 unsigned int dtype; 654 unsigned int dtype;
484 int i; 655 int i;
485 char *value; 656 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
486 657
487 /* Check parameters. */ 658 /* Check parameters. */
488 bus = args[0]; 659 bus = args[0];
489 service = args[1]; 660 service = args[1];
490 path = args[2]; 661 path = args[2];
527 for (i = 5; i < nargs; ++i) 698 for (i = 5; i < nargs; ++i)
528 { 699 {
529 700
530 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); 701 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
531 XD_DEBUG_MESSAGE ("Parameter%d %s", 702 XD_DEBUG_MESSAGE ("Parameter%d %s",
532 i-4, 703 i-4, SDATA (format2 ("%s", args[i], Qnil)));
533 SDATA (format2 ("%s", args[i], Qnil))); 704
534 705 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
535 dtype = XD_LISP_OBJECT_TO_DBUS_TYPE (args[i]); 706 if (XD_DBUS_TYPE_P (args[i]))
536 if (dtype == DBUS_TYPE_INVALID)
537 xsignal2 (Qdbus_error, build_string ("Not a valid argument"), args[i]);
538
539 if (SYMBOLP (args[i])
540 && (strncmp (SDATA (XSYMBOL (args[i])->xname), ":", 1) == 0))
541 ++i; 707 ++i;
708
709 /* Check for valid signature. We use DBUS_TYPE_INVALID is
710 indication that there is no parent type. */
711 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
542 712
543 xd_append_arg (dtype, args[i], &iter); 713 xd_append_arg (dtype, args[i], &iter);
544 } 714 }
545 715
546 /* Send the message. */ 716 /* Send the message. */
603 t and nil => DBUS_TYPE_BOOLEAN 773 t and nil => DBUS_TYPE_BOOLEAN
604 number => DBUS_TYPE_UINT32 774 number => DBUS_TYPE_UINT32
605 integer => DBUS_TYPE_INT32 775 integer => DBUS_TYPE_INT32
606 float => DBUS_TYPE_DOUBLE 776 float => DBUS_TYPE_DOUBLE
607 string => DBUS_TYPE_STRING 777 string => DBUS_TYPE_STRING
608 778 list => DBUS_TYPE_ARRAY
609 Other Lisp objects are not supported as arguments of SIGNAL. 779
780 All arguments can be preceded by a type symbol. For details about
781 type symbols, see Info node `(dbus)Type Conversion'.
610 782
611 Example: 783 Example:
612 784
613 \(dbus-send-signal 785 \(dbus-send-signal
614 :session "org.gnu.Emacs" "/org/gnu/Emacs" 786 :session "org.gnu.Emacs" "/org/gnu/Emacs"
624 DBusConnection *connection; 796 DBusConnection *connection;
625 DBusMessage *dmessage; 797 DBusMessage *dmessage;
626 DBusMessageIter iter; 798 DBusMessageIter iter;
627 unsigned int dtype; 799 unsigned int dtype;
628 int i; 800 int i;
629 char *value; 801 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
630 802
631 /* Check parameters. */ 803 /* Check parameters. */
632 bus = args[0]; 804 bus = args[0];
633 service = args[1]; 805 service = args[1];
634 path = args[2]; 806 path = args[2];
669 /* Append parameters to the message. */ 841 /* Append parameters to the message. */
670 for (i = 5; i < nargs; ++i) 842 for (i = 5; i < nargs; ++i)
671 { 843 {
672 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); 844 XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
673 XD_DEBUG_MESSAGE ("Parameter%d %s", 845 XD_DEBUG_MESSAGE ("Parameter%d %s",
674 i-4, 846 i-4, SDATA (format2 ("%s", args[i], Qnil)));
675 SDATA (format2 ("%s", args[i], Qnil))); 847
676 848 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
677 dtype = XD_LISP_OBJECT_TO_DBUS_TYPE (args[i]); 849 if (XD_DBUS_TYPE_P (args[i]))
678 if (dtype == DBUS_TYPE_INVALID)
679 xsignal2 (Qdbus_error, build_string ("Not a valid argument"), args[i]);
680
681 if (SYMBOLP (args[i])
682 && (strncmp (SDATA (XSYMBOL (args[i])->xname), ":", 1) == 0))
683 ++i; 850 ++i;
851
852 /* Check for valid signature. We use DBUS_TYPE_INVALID is
853 indication that there is no parent type. */
854 xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
684 855
685 xd_append_arg (dtype, args[i], &iter); 856 xd_append_arg (dtype, args[i], &iter);
686 } 857 }
687 858
688 /* Send the message. The message is just added to the outgoing 859 /* Send the message. The message is just added to the outgoing