diff options
| author | Michael Albinus | 2007-12-21 22:01:43 +0000 |
|---|---|---|
| committer | Michael Albinus | 2007-12-21 22:01:43 +0000 |
| commit | 87cf1a39ef9ba9e445e3130614b8eecf4dc57a35 (patch) | |
| tree | 45800764fde752a913df8b1c199c47c8446c259a /src | |
| parent | 62b12a24575fde84f735621c7c8e9dd328cc5400 (diff) | |
| download | emacs-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/ChangeLog | 14 | ||||
| -rw-r--r-- | src/dbusbind.c | 433 |
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 @@ | |||
| 1 | 2007-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 | |||
| 1 | 2007-12-19 Michael Albinus <michael.albinus@gmx.de> | 15 | 2007-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. */ | ||
| 150 | void | 173 | void |
| 151 | xd_append_arg (dtype, object, iter) | 174 | xd_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. */ | ||
| 324 | void | ||
| 325 | xd_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 | ||
| 443 | Other Lisp objects are not supported as input arguments of METHOD. | 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" |
| @@ -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 | ||
| 609 | Other Lisp objects are not supported as arguments of SIGNAL. | 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 | ||
| @@ -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 | ||