aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Albinus2007-12-21 22:01:43 +0000
committerMichael Albinus2007-12-21 22:01:43 +0000
commit87cf1a39ef9ba9e445e3130614b8eecf4dc57a35 (patch)
tree45800764fde752a913df8b1c199c47c8446c259a /src
parent62b12a24575fde84f735621c7c8e9dd328cc5400 (diff)
downloademacs-87cf1a39ef9ba9e445e3130614b8eecf4dc57a35.tar.gz
emacs-87cf1a39ef9ba9e445e3130614b8eecf4dc57a35.zip
* 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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog14
-rw-r--r--src/dbusbind.c433
2 files changed, 316 insertions, 131 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 85fb6b357c2..7c2bbffd1e4 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,17 @@
12007-12-21 Michael Albinus <michael.albinus@gmx.de>
2
3 * dbusbind.c (XD_BASIC_DBUS_TYPE, XD_DBUS_TYPE_P, XD_NEXT_VALUE):
4 New macros.
5 (XD_SYMBOL_TO_DBUS_TYPE): Renamed from
6 XD_LISP_SYMBOL_TO_DBUS_TYPE.
7 (XD_OBJECT_TO_DBUS_TYPE): Renamed from
8 XD_LISP_OBJECT_TO_DBUS_TYPE. Simplify.
9 (xd_signature): New function.
10 (xd_append_arg): Compute also signatures. Major rewrite.
11 (xd_retrieve_arg): Make debug messages friendly.
12 (Fdbus_call_method, Fdbus_send_signal): Extend docstring. Check
13 for signatures of arguments.
14
12007-12-19 Michael Albinus <michael.albinus@gmx.de> 152007-12-19 Michael Albinus <michael.albinus@gmx.de>
2 16
3 * dbusbind.c (QCdbus_type_byte, QCdbus_type_boolean) 17 * dbusbind.c (QCdbus_type_byte, QCdbus_type_boolean)
diff --git a/src/dbusbind.c b/src/dbusbind.c
index a8e5f4f0ddf..01168f51a95 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -103,61 +103,85 @@ Lisp_Object Vdbus_debug;
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. */
144 163#define XD_NEXT_VALUE(object) \
145/* Append C value, extracted from Lisp OBJECT, to iteration ITER. 164 ((XD_DBUS_TYPE_P (XCAR (object))) ? XCDR (object) : object)
146 DTYPE must be a valid DBusType. It is used to convert Lisp 165
147 objects, being arguments of `dbus-call-method' or 166/* Compute SIGNATURE of OBJECT. It must have a form that it can be
148 `dbus-send-signal', into corresponding C values appended as 167 used in dbus_message_iter_open_container. DTYPE is the DBusType
149 arguments to a D-Bus message. */ 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. */
150void 173void
151xd_append_arg (dtype, object, iter) 174xd_signature(signature, dtype, parent_type, object)
152 unsigned int dtype; 175 char *signature;
153 DBusMessageIter *iter; 176 unsigned int dtype, parent_type;
154 Lisp_Object object; 177 Lisp_Object object;
155{ 178{
156 char *value; 179 unsigned int subtype;
180 Lisp_Object elt;
181 char x[DBUS_MAXIMUM_SIGNATURE_LENGTH];
182
183 elt = object;
157 184
158 /* Check type of object. If this has been detected implicitely, it
159 is OK already, but there might be cases the type symbol and the
160 corresponding object do'nt match. */
161 switch (dtype) 185 switch (dtype)
162 { 186 {
163 case DBUS_TYPE_BYTE: 187 case DBUS_TYPE_BYTE:
@@ -165,143 +189,269 @@ xd_append_arg (dtype, object, iter)
165 case DBUS_TYPE_UINT32: 189 case DBUS_TYPE_UINT32:
166 case DBUS_TYPE_UINT64: 190 case DBUS_TYPE_UINT64:
167 CHECK_NATNUM (object); 191 CHECK_NATNUM (object);
192 sprintf (signature, "%c", dtype);
168 break; 193 break;
194
169 case DBUS_TYPE_BOOLEAN: 195 case DBUS_TYPE_BOOLEAN:
170 if (!EQ (object, Qt) && !EQ (object, Qnil)) 196 if (!EQ (object, Qt) && !EQ (object, Qnil))
171 wrong_type_argument (intern ("booleanp"), object); 197 wrong_type_argument (intern ("booleanp"), object);
198 sprintf (signature, "%c", dtype);
172 break; 199 break;
200
173 case DBUS_TYPE_INT16: 201 case DBUS_TYPE_INT16:
174 case DBUS_TYPE_INT32: 202 case DBUS_TYPE_INT32:
175 case DBUS_TYPE_INT64: 203 case DBUS_TYPE_INT64:
176 CHECK_NUMBER (object); 204 CHECK_NUMBER (object);
205 sprintf (signature, "%c", dtype);
177 break; 206 break;
207
178 case DBUS_TYPE_DOUBLE: 208 case DBUS_TYPE_DOUBLE:
179 CHECK_FLOAT (object); 209 CHECK_FLOAT (object);
210 sprintf (signature, "%c", dtype);
180 break; 211 break;
212
181 case DBUS_TYPE_STRING: 213 case DBUS_TYPE_STRING:
182 case DBUS_TYPE_OBJECT_PATH: 214 case DBUS_TYPE_OBJECT_PATH:
183 case DBUS_TYPE_SIGNATURE: 215 case DBUS_TYPE_SIGNATURE:
184 CHECK_STRING (object); 216 CHECK_STRING (object);
217 sprintf (signature, "%c", dtype);
185 break; 218 break;
219
186 case DBUS_TYPE_ARRAY: 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. */
187 CHECK_CONS (object); 224 CHECK_CONS (object);
188 /* ToDo: Check that all list elements have the same type. */ 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);
189 break; 239 break;
240
190 case DBUS_TYPE_VARIANT: 241 case DBUS_TYPE_VARIANT:
242 /* Check that there is exactly one element. */
191 CHECK_CONS (object); 243 CHECK_CONS (object);
192 /* ToDo: Check that there is exactly one element of basic type. */ 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);
193 break; 254 break;
255
194 case DBUS_TYPE_STRUCT: 256 case DBUS_TYPE_STRUCT:
195 CHECK_CONS (object); 257 /* A struct might contain any number of objects with different
196 break; 258 types. No further check needed. */
197 case DBUS_TYPE_DICT_ENTRY: 259 CHECK_CONS (object);
198 /* ToDo: Check that there are exactly two elements, and the 260
199 first one is of basic type. */ 261 elt = XD_NEXT_VALUE (elt);
200 CHECK_CONS (object); 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);
201 break; 274 break;
202 default:
203 xsignal1 (Qdbus_error, build_string ("Unknown D-Bus type"));
204 }
205 275
206 if (CONSP (object)) 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);
207 281
208 /* Compound types. */ 282 if (parent_type != DBUS_TYPE_ARRAY)
209 { 283 wrong_type_argument (intern ("D-Bus"), object);
210 DBusMessageIter subiter;
211 char subtype;
212 284
213 if (SYMBOLP (XCAR (object)) 285 /* Compose the signature from the elements. It is enclosed by
214 && (strncmp (SDATA (XSYMBOL (XCAR (object))->xname), ":", 1) == 0)) 286 curly braces. */
215 object = XCDR (object); 287 sprintf (signature, "%c", DBUS_DICT_ENTRY_BEGIN_CHAR);
216 288
217 /* Open new subiteration. */ 289 /* First element. */
218 switch (dtype) 290 elt = XD_NEXT_VALUE (elt);
219 { 291 subtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (elt));
220 case DBUS_TYPE_ARRAY: 292 xd_signature (x, subtype, dtype, XCAR (XD_NEXT_VALUE (elt)));
221 case DBUS_TYPE_VARIANT: 293 strcat (signature, x);
222 subtype = (char) XD_LISP_OBJECT_TO_DBUS_TYPE (XCAR (object));
223 dbus_message_iter_open_container (iter, dtype, &subtype, &subiter);
224 break;
225 case DBUS_TYPE_STRUCT:
226 case DBUS_TYPE_DICT_ENTRY:
227 dbus_message_iter_open_container (iter, dtype, NULL, &subiter);
228 }
229 294
230 /* Loop over list elements. */ 295 if (!XD_BASIC_DBUS_TYPE (subtype))
231 while (!NILP (object)) 296 wrong_type_argument (intern ("D-Bus"), XCAR (XD_NEXT_VALUE (elt)));
232 {
233 dtype = XD_LISP_OBJECT_TO_DBUS_TYPE (XCAR (object));
234 if (dtype == DBUS_TYPE_INVALID)
235 xsignal2 (Qdbus_error,
236 build_string ("Not a valid argument"), XCAR (object));
237 297
238 if (SYMBOLP (XCAR (object)) 298 /* Second element. */
239 && (strncmp (SDATA (XSYMBOL (XCAR (object))->xname), ":", 1) 299 elt = XCDR (XD_NEXT_VALUE (elt));
240 == 0)) 300 subtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (elt));
241 object = XCDR (object); 301 xd_signature (x, subtype, dtype, XCAR (XD_NEXT_VALUE (elt)));
302 strcat (signature, x);
242 303
243 xd_append_arg (dtype, XCAR (object), &subiter); 304 if (!NILP (XCDR (XD_NEXT_VALUE (elt))))
305 wrong_type_argument (intern ("D-Bus"),
306 XCAR (XCDR (XD_NEXT_VALUE (elt))));
244 307
245 object = XCDR (object); 308 /* Closing signature. */
246 } 309 sprintf (signature, "%s%c", signature, DBUS_DICT_ENTRY_END_CHAR);
310 break;
247 311
248 dbus_message_iter_close_container (iter, &subiter); 312 default:
313 wrong_type_argument (intern ("D-Bus"), object);
249 } 314 }
250 315
251 else 316 XD_DEBUG_MESSAGE ("%s", signature);
317}
252 318
253 /* Basic type. */ 319/* Append C value, extracted from Lisp OBJECT, to iteration ITER.
320 DTYPE must be a valid DBusType. It is used to convert Lisp
321 objects, being arguments of `dbus-call-method' or
322 `dbus-send-signal', into corresponding C values appended as
323 arguments to a D-Bus message. */
324void
325xd_append_arg (dtype, object, iter)
326 unsigned int dtype;
327 Lisp_Object object;
328 DBusMessageIter *iter;
329{
330 Lisp_Object elt;
331 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
332 DBusMessageIter subiter;
333 char *value;
334
335 XD_DEBUG_MESSAGE ("%c %s", dtype, SDATA (format2 ("%s", object, Qnil)));
336
337 if (XD_BASIC_DBUS_TYPE (dtype))
254 { 338 {
255 switch (dtype) 339 switch (dtype)
256 { 340 {
257 case DBUS_TYPE_BYTE: 341 case DBUS_TYPE_BYTE:
258 XD_DEBUG_MESSAGE ("%d %u", dtype, XUINT (object)); 342 XD_DEBUG_MESSAGE ("%c %u", dtype, XUINT (object));
259 value = (unsigned char *) XUINT (object); 343 value = (unsigned char *) XUINT (object);
260 break; 344 break;
345
261 case DBUS_TYPE_BOOLEAN: 346 case DBUS_TYPE_BOOLEAN:
262 XD_DEBUG_MESSAGE ("%d %s", dtype, (NILP (object)) ? "false" : "true"); 347 XD_DEBUG_MESSAGE ("%c %s", dtype, (NILP (object)) ? "false" : "true");
263 value = (NILP (object)) 348 value = (NILP (object))
264 ? (unsigned char *) FALSE : (unsigned char *) TRUE; 349 ? (unsigned char *) FALSE : (unsigned char *) TRUE;
265 break; 350 break;
351
266 case DBUS_TYPE_INT16: 352 case DBUS_TYPE_INT16:
267 XD_DEBUG_MESSAGE ("%d %d", dtype, XINT (object)); 353 XD_DEBUG_MESSAGE ("%c %d", dtype, XINT (object));
268 value = (char *) (dbus_int16_t *) XINT (object); 354 value = (char *) (dbus_int16_t *) XINT (object);
269 break; 355 break;
356
270 case DBUS_TYPE_UINT16: 357 case DBUS_TYPE_UINT16:
271 XD_DEBUG_MESSAGE ("%d %u", dtype, XUINT (object)); 358 XD_DEBUG_MESSAGE ("%c %u", dtype, XUINT (object));
272 value = (char *) (dbus_uint16_t *) XUINT (object); 359 value = (char *) (dbus_uint16_t *) XUINT (object);
273 break; 360 break;
361
274 case DBUS_TYPE_INT32: 362 case DBUS_TYPE_INT32:
275 XD_DEBUG_MESSAGE ("%d %d", dtype, XINT (object)); 363 XD_DEBUG_MESSAGE ("%c %d", dtype, XINT (object));
276 value = (char *) (dbus_int32_t *) XINT (object); 364 value = (char *) (dbus_int32_t *) XINT (object);
277 break; 365 break;
366
278 case DBUS_TYPE_UINT32: 367 case DBUS_TYPE_UINT32:
279 XD_DEBUG_MESSAGE ("%d %u", dtype, XUINT (object)); 368 XD_DEBUG_MESSAGE ("%c %u", dtype, XUINT (object));
280 value = (char *) (dbus_uint32_t *) XUINT (object); 369 value = (char *) (dbus_uint32_t *) XUINT (object);
281 break; 370 break;
371
282 case DBUS_TYPE_INT64: 372 case DBUS_TYPE_INT64:
283 XD_DEBUG_MESSAGE ("%d %d", dtype, XINT (object)); 373 XD_DEBUG_MESSAGE ("%c %d", dtype, XINT (object));
284 value = (char *) (dbus_int64_t *) XINT (object); 374 value = (char *) (dbus_int64_t *) XINT (object);
285 break; 375 break;
376
286 case DBUS_TYPE_UINT64: 377 case DBUS_TYPE_UINT64:
287 XD_DEBUG_MESSAGE ("%d %u", dtype, XUINT (object)); 378 XD_DEBUG_MESSAGE ("%c %u", dtype, XUINT (object));
288 value = (char *) (dbus_int64_t *) XUINT (object); 379 value = (char *) (dbus_int64_t *) XUINT (object);
289 break; 380 break;
381
290 case DBUS_TYPE_DOUBLE: 382 case DBUS_TYPE_DOUBLE:
291 XD_DEBUG_MESSAGE ("%d %f", dtype, XFLOAT (object)); 383 XD_DEBUG_MESSAGE ("%c %f", dtype, XFLOAT (object));
292 value = (char *) (float *) XFLOAT (object); 384 value = (char *) (float *) XFLOAT (object);
293 break; 385 break;
386
294 case DBUS_TYPE_STRING: 387 case DBUS_TYPE_STRING:
295 case DBUS_TYPE_OBJECT_PATH: 388 case DBUS_TYPE_OBJECT_PATH:
296 case DBUS_TYPE_SIGNATURE: 389 case DBUS_TYPE_SIGNATURE:
297 XD_DEBUG_MESSAGE ("%d %s", dtype, SDATA (object)); 390 XD_DEBUG_MESSAGE ("%c %s", dtype, SDATA (object));
298 value = SDATA (object); 391 value = SDATA (object);
299 break; 392 break;
300 } 393 }
394
301 if (!dbus_message_iter_append_basic (iter, dtype, &value)) 395 if (!dbus_message_iter_append_basic (iter, dtype, &value))
302 xsignal2 (Qdbus_error, 396 xsignal2 (Qdbus_error,
303 build_string ("Unable to append argument"), object); 397 build_string ("Unable to append argument"), object);
304 } 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);
407
408 /* Open new subiteration. */
409 switch (dtype)
410 {
411 case DBUS_TYPE_ARRAY:
412 case DBUS_TYPE_VARIANT:
413 /* A variant has just one element. An array has elements of
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));
426 break;
427
428 case DBUS_TYPE_STRUCT:
429 case DBUS_TYPE_DICT_ENTRY:
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;
437 }
438
439 /* Loop over list elements. */
440 while (!NILP (object))
441 {
442 dtype = XD_OBJECT_TO_DBUS_TYPE (XCAR (object));
443 object = XD_NEXT_VALUE (object);
444
445 xd_append_arg (dtype, XCAR (object), &subiter);
446
447 object = XCDR (object);
448 }
449
450 if (!dbus_message_iter_close_container (iter, &subiter))
451 xsignal2 (Qdbus_error,
452 build_string ("Cannot close container"),
453 make_number (dtype));
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
@@ -320,25 +470,28 @@ xd_retrieve_arg (dtype, iter)
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:
@@ -359,8 +512,9 @@ xd_retrieve_arg (dtype, iter)
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}
@@ -439,16 +593,33 @@ converted into D-Bus types via the following rules:
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
596 list => DBUS_TYPE_ARRAY
442 597
443Other Lisp objects are not supported as input arguments of METHOD. 598All arguments can be preceded by a type symbol. For details about
599type 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
446Lisp objects. The type conversion happens the other direction as for 602Lisp objects. The type conversion happens the other direction as for
447input arguments. Additionally to the types supported for input 603input arguments. It follows the mapping rules:
448arguments, the D-Bus compound types DBUS_TYPE_ARRAY, DBUS_TYPE_VARIANT, 604
449DBUS_TYPE_STRUCT and DBUS_TYPE_DICT_ENTRY are accepted. All of them 605 DBUS_TYPE_BOOLEAN => t or nil
450are converted into a list of Lisp objects which correspond to the 606 DBUS_TYPE_BYTE => number
451elements 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
622Example:
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"
@@ -482,7 +653,7 @@ usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &rest ARGS) */)
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];
@@ -529,17 +700,16 @@ usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &rest ARGS) */)
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)));
534 704
535 dtype = XD_LISP_OBJECT_TO_DBUS_TYPE (args[i]); 705 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
536 if (dtype == DBUS_TYPE_INVALID) 706 if (XD_DBUS_TYPE_P (args[i]))
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;
542 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]);
712
543 xd_append_arg (dtype, args[i], &iter); 713 xd_append_arg (dtype, args[i], &iter);
544 } 714 }
545 715
@@ -605,8 +775,10 @@ converted into D-Bus types via the following rules:
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
778 list => DBUS_TYPE_ARRAY
608 779
609Other Lisp objects are not supported as arguments of SIGNAL. 780All arguments can be preceded by a type symbol. For details about
781type symbols, see Info node `(dbus)Type Conversion'.
610 782
611Example: 783Example:
612 784
@@ -626,7 +798,7 @@ usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
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];
@@ -671,17 +843,16 @@ usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
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)));
676
677 dtype = XD_LISP_OBJECT_TO_DBUS_TYPE (args[i]);
678 if (dtype == DBUS_TYPE_INVALID)
679 xsignal2 (Qdbus_error, build_string ("Not a valid argument"), args[i]);
680 847
681 if (SYMBOLP (args[i]) 848 dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
682 && (strncmp (SDATA (XSYMBOL (args[i])->xname), ":", 1) == 0)) 849 if (XD_DBUS_TYPE_P (args[i]))
683 ++i; 850 ++i;
684 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]);
855
685 xd_append_arg (dtype, args[i], &iter); 856 xd_append_arg (dtype, args[i], &iter);
686 } 857 }
687 858