aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Albinus2007-12-19 22:50:22 +0000
committerMichael Albinus2007-12-19 22:50:22 +0000
commit54371585f73e169cd80782592b87d91d4d6bfbfd (patch)
tree4830aecd0806336bd2fdedfcfe4cde67636be008 /src
parentd57d5a78ba4f2625e86893d2a86e41e53879a581 (diff)
downloademacs-54371585f73e169cd80782592b87d91d4d6bfbfd.tar.gz
emacs-54371585f73e169cd80782592b87d91d4d6bfbfd.zip
* dbusbind.c (QCdbus_type_byte, QCdbus_type_boolean)
(QCdbus_type_int16, QCdbus_type_uint16, QCdbus_type_int32) (QCdbus_type_uint32, QCdbus_type_int64, QCdbus_type_uint64) (QCdbus_type_double, QCdbus_type_string, QCdbus_type_object_path) (QCdbus_type_signature, QCdbus_type_array, QCdbus_type_variant) (QCdbus_type_struct, QCdbus_type_dict_entry): New D-Bus type symbols. (XD_LISP_SYMBOL_TO_DBUS_TYPE): New macro. (XD_LISP_OBJECT_TO_DBUS_TYPE): Add compound types. (xd_retrieve_value): Removed. Functionality included in ... (xd_append_arg): New function. (Fdbus_call_method, Fdbus_send_signal): Apply it.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog15
-rw-r--r--src/dbusbind.c302
2 files changed, 272 insertions, 45 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 57d548a315c..85fb6b357c2 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,18 @@
12007-12-19 Michael Albinus <michael.albinus@gmx.de>
2
3 * dbusbind.c (QCdbus_type_byte, QCdbus_type_boolean)
4 (QCdbus_type_int16, QCdbus_type_uint16, QCdbus_type_int32)
5 (QCdbus_type_uint32, QCdbus_type_int64, QCdbus_type_uint64)
6 (QCdbus_type_double, QCdbus_type_string, QCdbus_type_object_path)
7 (QCdbus_type_signature, QCdbus_type_array, QCdbus_type_variant)
8 (QCdbus_type_struct, QCdbus_type_dict_entry): New D-Bus type
9 symbols.
10 (XD_LISP_SYMBOL_TO_DBUS_TYPE): New macro.
11 (XD_LISP_OBJECT_TO_DBUS_TYPE): Add compound types.
12 (xd_retrieve_value): Removed. Functionality included in ...
13 (xd_append_arg): New function.
14 (Fdbus_call_method, Fdbus_send_signal): Apply it.
15
12007-12-16 Michael Albinus <michael.albinus@gmx.de> 162007-12-16 Michael Albinus <michael.albinus@gmx.de>
2 17
3 * dbusbind.c (top): Include <stdio.h>. 18 * dbusbind.c (top): Include <stdio.h>.
diff --git a/src/dbusbind.c b/src/dbusbind.c
index d4008f7314c..a8e5f4f0ddf 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -43,6 +43,16 @@ Lisp_Object Qdbus_error;
43/* Lisp symbols of the system and session buses. */ 43/* Lisp symbols of the system and session buses. */
44Lisp_Object QCdbus_system_bus, QCdbus_session_bus; 44Lisp_Object QCdbus_system_bus, QCdbus_session_bus;
45 45
46/* Lisp symbols of D-Bus types. */
47Lisp_Object QCdbus_type_byte, QCdbus_type_boolean;
48Lisp_Object QCdbus_type_int16, QCdbus_type_uint16;
49Lisp_Object QCdbus_type_int32, QCdbus_type_uint32;
50Lisp_Object QCdbus_type_int64, QCdbus_type_uint64;
51Lisp_Object QCdbus_type_double, QCdbus_type_string;
52Lisp_Object QCdbus_type_object_path, QCdbus_type_signature;
53Lisp_Object QCdbus_type_array, QCdbus_type_variant;
54Lisp_Object QCdbus_type_struct, QCdbus_type_dict_entry;
55
46/* Hash table which keeps function definitions. */ 56/* Hash table which keeps function definitions. */
47Lisp_Object Vdbus_registered_functions_table; 57Lisp_Object Vdbus_registered_functions_table;
48 58
@@ -53,7 +63,7 @@ Lisp_Object Vdbus_debug;
53/* We use "xd_" and "XD_" as prefix for all internal symbols, because 63/* We use "xd_" and "XD_" as prefix for all internal symbols, because
54 we don't want to poison other namespaces with "dbus_". */ 64 we don't want to poison other namespaces with "dbus_". */
55 65
56/* Raise a Lisp error from a D-Bus error. */ 66/* Raise a Lisp error from a D-Bus ERROR. */
57#define XD_ERROR(error) \ 67#define XD_ERROR(error) \
58 { \ 68 { \
59 char s[1024]; \ 69 char s[1024]; \
@@ -93,51 +103,204 @@ Lisp_Object Vdbus_debug;
93#define XD_DEBUG_VALID_LISP_OBJECT_P(object) 103#define XD_DEBUG_VALID_LISP_OBJECT_P(object)
94#endif 104#endif
95 105
96/* Determine the DBusType of a given Lisp object. It is used to 106/* Determine the DBusType of a given Lisp symbol. OBJECT must be one
107 of the predefined D-Bus type symbols. */
108#define XD_LISP_SYMBOL_TO_DBUS_TYPE(object) \
109 (EQ (object, QCdbus_type_byte)) ? DBUS_TYPE_BYTE \
110 : (EQ (object, QCdbus_type_boolean)) ? DBUS_TYPE_BOOLEAN \
111 : (EQ (object, QCdbus_type_int16)) ? DBUS_TYPE_INT16 \
112 : (EQ (object, QCdbus_type_uint16)) ? DBUS_TYPE_UINT16 \
113 : (EQ (object, QCdbus_type_int32)) ? DBUS_TYPE_INT32 \
114 : (EQ (object, QCdbus_type_uint32)) ? DBUS_TYPE_UINT32 \
115 : (EQ (object, QCdbus_type_int64)) ? DBUS_TYPE_INT64 \
116 : (EQ (object, QCdbus_type_uint64)) ? DBUS_TYPE_UINT64 \
117 : (EQ (object, QCdbus_type_double)) ? DBUS_TYPE_DOUBLE \
118 : (EQ (object, QCdbus_type_string)) ? DBUS_TYPE_STRING \
119 : (EQ (object, QCdbus_type_object_path)) ? DBUS_TYPE_OBJECT_PATH \
120 : (EQ (object, QCdbus_type_signature)) ? DBUS_TYPE_SIGNATURE \
121 : (EQ (object, QCdbus_type_array)) ? DBUS_TYPE_ARRAY \
122 : (EQ (object, QCdbus_type_variant)) ? DBUS_TYPE_VARIANT \
123 : (EQ (object, QCdbus_type_struct)) ? DBUS_TYPE_STRUCT \
124 : (EQ (object, QCdbus_type_dict_entry)) ? DBUS_TYPE_DICT_ENTRY \
125 : DBUS_TYPE_INVALID
126
127/* Determine the DBusType of a given Lisp OBJECT. It is used to
97 convert Lisp objects, being arguments of `dbus-call-method' or 128 convert Lisp objects, being arguments of `dbus-call-method' or
98 `dbus-send-signal', into corresponding C values appended as 129 `dbus-send-signal', into corresponding C values appended as
99 arguments to a D-Bus message. */ 130 arguments to a D-Bus message. */
100#define XD_LISP_OBJECT_TO_DBUS_TYPE(object) \ 131#define XD_LISP_OBJECT_TO_DBUS_TYPE(object) \
101 (EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN : \ 132 (EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN \
102 (NATNUMP (object)) ? DBUS_TYPE_UINT32 : \ 133 : (SYMBOLP (object)) ? XD_LISP_SYMBOL_TO_DBUS_TYPE (object) \
103 (INTEGERP (object)) ? DBUS_TYPE_INT32 : \ 134 : (CONSP (object)) ? ((SYMBOLP (XCAR (object)) \
104 (FLOATP (object)) ? DBUS_TYPE_DOUBLE : \ 135 && !EQ (XCAR (object), Qt) \
105 (STRINGP (object)) ? DBUS_TYPE_STRING : \ 136 && !EQ (XCAR (object), Qnil)) \
106 DBUS_TYPE_INVALID 137 ? XD_LISP_SYMBOL_TO_DBUS_TYPE (XCAR (object)) \
107 138 : DBUS_TYPE_ARRAY) \
108/* Extract C value from Lisp OBJECT. DTYPE must be a valid DBusType, 139 : (NATNUMP (object)) ? DBUS_TYPE_UINT32 \
109 as detected by XD_LISP_OBJECT_TO_DBUS_TYPE. Compound types are not 140 : (INTEGERP (object)) ? DBUS_TYPE_INT32 \
110 supported (yet). It is used to convert Lisp objects, being 141 : (FLOATP (object)) ? DBUS_TYPE_DOUBLE \
111 arguments of `dbus-call-method' or `dbus-send-signal', into 142 : (STRINGP (object)) ? DBUS_TYPE_STRING \
112 corresponding C values appended as arguments to a D-Bus 143 : DBUS_TYPE_INVALID
113 message. */ 144
114char * 145/* Append C value, extracted from Lisp OBJECT, to iteration ITER.
115xd_retrieve_value (dtype, object) 146 DTYPE must be a valid DBusType. It is used to convert Lisp
147 objects, being arguments of `dbus-call-method' or
148 `dbus-send-signal', into corresponding C values appended as
149 arguments to a D-Bus message. */
150void
151xd_append_arg (dtype, object, iter)
116 unsigned int dtype; 152 unsigned int dtype;
153 DBusMessageIter *iter;
117 Lisp_Object object; 154 Lisp_Object object;
118{ 155{
156 char *value;
119 157
120 XD_DEBUG_VALID_LISP_OBJECT_P (object); 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. */
121 switch (dtype) 161 switch (dtype)
122 { 162 {
123 case DBUS_TYPE_BOOLEAN: 163 case DBUS_TYPE_BYTE:
124 XD_DEBUG_MESSAGE ("%d %s", dtype, (NILP (object)) ? "false" : "true"); 164 case DBUS_TYPE_UINT16:
125 return (NILP (object)) ? (char *) FALSE : (char *) TRUE;
126 case DBUS_TYPE_UINT32: 165 case DBUS_TYPE_UINT32:
127 XD_DEBUG_MESSAGE ("%d %d", dtype, XUINT (object)); 166 case DBUS_TYPE_UINT64:
128 return (char *) XUINT (object); 167 CHECK_NATNUM (object);
168 break;
169 case DBUS_TYPE_BOOLEAN:
170 if (!EQ (object, Qt) && !EQ (object, Qnil))
171 wrong_type_argument (intern ("booleanp"), object);
172 break;
173 case DBUS_TYPE_INT16:
129 case DBUS_TYPE_INT32: 174 case DBUS_TYPE_INT32:
130 XD_DEBUG_MESSAGE ("%d %d", dtype, XINT (object)); 175 case DBUS_TYPE_INT64:
131 return (char *) XINT (object); 176 CHECK_NUMBER (object);
177 break;
132 case DBUS_TYPE_DOUBLE: 178 case DBUS_TYPE_DOUBLE:
133 XD_DEBUG_MESSAGE ("%d %d", dtype, XFLOAT (object)); 179 CHECK_FLOAT (object);
134 return (char *) XFLOAT (object); 180 break;
135 case DBUS_TYPE_STRING: 181 case DBUS_TYPE_STRING:
136 XD_DEBUG_MESSAGE ("%d %s", dtype, SDATA (object)); 182 case DBUS_TYPE_OBJECT_PATH:
137 return SDATA (object); 183 case DBUS_TYPE_SIGNATURE:
184 CHECK_STRING (object);
185 break;
186 case DBUS_TYPE_ARRAY:
187 CHECK_CONS (object);
188 /* ToDo: Check that all list elements have the same type. */
189 break;
190 case DBUS_TYPE_VARIANT:
191 CHECK_CONS (object);
192 /* ToDo: Check that there is exactly one element of basic type. */
193 break;
194 case DBUS_TYPE_STRUCT:
195 CHECK_CONS (object);
196 break;
197 case DBUS_TYPE_DICT_ENTRY:
198 /* ToDo: Check that there are exactly two elements, and the
199 first one is of basic type. */
200 CHECK_CONS (object);
201 break;
138 default: 202 default:
139 XD_DEBUG_MESSAGE ("DBus-Type %d not supported", dtype); 203 xsignal1 (Qdbus_error, build_string ("Unknown D-Bus type"));
140 return NULL; 204 }
205
206 if (CONSP (object))
207
208 /* Compound types. */
209 {
210 DBusMessageIter subiter;
211 char subtype;
212
213 if (SYMBOLP (XCAR (object))
214 && (strncmp (SDATA (XSYMBOL (XCAR (object))->xname), ":", 1) == 0))
215 object = XCDR (object);
216
217 /* Open new subiteration. */
218 switch (dtype)
219 {
220 case DBUS_TYPE_ARRAY:
221 case DBUS_TYPE_VARIANT:
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
230 /* Loop over list elements. */
231 while (!NILP (object))
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
238 if (SYMBOLP (XCAR (object))
239 && (strncmp (SDATA (XSYMBOL (XCAR (object))->xname), ":", 1)
240 == 0))
241 object = XCDR (object);
242
243 xd_append_arg (dtype, XCAR (object), &subiter);
244
245 object = XCDR (object);
246 }
247
248 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,
303 build_string ("Unable to append argument"), object);
141 } 304 }
142} 305}
143 306
@@ -357,6 +520,9 @@ usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &rest ARGS) */)
357 520
358 UNGCPRO; 521 UNGCPRO;
359 522
523 /* Initialize parameter list of message. */
524 dbus_message_iter_init_append (dmessage, &iter);
525
360 /* Append parameters to the message. */ 526 /* Append parameters to the message. */
361 for (i = 5; i < nargs; ++i) 527 for (i = 5; i < nargs; ++i)
362 { 528 {
@@ -370,14 +536,11 @@ usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &rest ARGS) */)
370 if (dtype == DBUS_TYPE_INVALID) 536 if (dtype == DBUS_TYPE_INVALID)
371 xsignal2 (Qdbus_error, build_string ("Not a valid argument"), args[i]); 537 xsignal2 (Qdbus_error, build_string ("Not a valid argument"), args[i]);
372 538
373 value = (char *) xd_retrieve_value (dtype, args[i]); 539 if (SYMBOLP (args[i])
540 && (strncmp (SDATA (XSYMBOL (args[i])->xname), ":", 1) == 0))
541 ++i;
374 542
375 if (!dbus_message_append_args (dmessage, 543 xd_append_arg (dtype, args[i], &iter);
376 dtype,
377 &value,
378 DBUS_TYPE_INVALID))
379 xsignal2 (Qdbus_error,
380 build_string ("Unable to append argument"), args[i]);
381 } 544 }
382 545
383 /* Send the message. */ 546 /* Send the message. */
@@ -460,6 +623,7 @@ usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
460 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 623 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
461 DBusConnection *connection; 624 DBusConnection *connection;
462 DBusMessage *dmessage; 625 DBusMessage *dmessage;
626 DBusMessageIter iter;
463 unsigned int dtype; 627 unsigned int dtype;
464 int i; 628 int i;
465 char *value; 629 char *value;
@@ -499,6 +663,9 @@ usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
499 663
500 UNGCPRO; 664 UNGCPRO;
501 665
666 /* Initialize parameter list of message. */
667 dbus_message_iter_init_append (dmessage, &iter);
668
502 /* Append parameters to the message. */ 669 /* Append parameters to the message. */
503 for (i = 5; i < nargs; ++i) 670 for (i = 5; i < nargs; ++i)
504 { 671 {
@@ -511,14 +678,11 @@ usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
511 if (dtype == DBUS_TYPE_INVALID) 678 if (dtype == DBUS_TYPE_INVALID)
512 xsignal2 (Qdbus_error, build_string ("Not a valid argument"), args[i]); 679 xsignal2 (Qdbus_error, build_string ("Not a valid argument"), args[i]);
513 680
514 value = (char *) xd_retrieve_value (dtype, args[i]); 681 if (SYMBOLP (args[i])
682 && (strncmp (SDATA (XSYMBOL (args[i])->xname), ":", 1) == 0))
683 ++i;
515 684
516 if (!dbus_message_append_args (dmessage, 685 xd_append_arg (dtype, args[i], &iter);
517 dtype,
518 &value,
519 DBUS_TYPE_INVALID))
520 xsignal2 (Qdbus_error,
521 build_string ("Unable to append argument"), args[i]);
522 } 686 }
523 687
524 /* Send the message. The message is just added to the outgoing 688 /* Send the message. The message is just added to the outgoing
@@ -850,6 +1014,54 @@ syms_of_dbusbind ()
850 QCdbus_session_bus = intern (":session"); 1014 QCdbus_session_bus = intern (":session");
851 staticpro (&QCdbus_session_bus); 1015 staticpro (&QCdbus_session_bus);
852 1016
1017 QCdbus_type_byte = intern (":byte");
1018 staticpro (&QCdbus_type_byte);
1019
1020 QCdbus_type_boolean = intern (":boolean");
1021 staticpro (&QCdbus_type_boolean);
1022
1023 QCdbus_type_int16 = intern (":int16");
1024 staticpro (&QCdbus_type_int16);
1025
1026 QCdbus_type_uint16 = intern (":uint16");
1027 staticpro (&QCdbus_type_uint16);
1028
1029 QCdbus_type_int32 = intern (":int32");
1030 staticpro (&QCdbus_type_int32);
1031
1032 QCdbus_type_uint32 = intern (":uint32");
1033 staticpro (&QCdbus_type_uint32);
1034
1035 QCdbus_type_int64 = intern (":int64");
1036 staticpro (&QCdbus_type_int64);
1037
1038 QCdbus_type_uint64 = intern (":uint64");
1039 staticpro (&QCdbus_type_uint64);
1040
1041 QCdbus_type_double = intern (":double");
1042 staticpro (&QCdbus_type_double);
1043
1044 QCdbus_type_string = intern (":string");
1045 staticpro (&QCdbus_type_string);
1046
1047 QCdbus_type_object_path = intern (":object-path");
1048 staticpro (&QCdbus_type_object_path);
1049
1050 QCdbus_type_signature = intern (":signature");
1051 staticpro (&QCdbus_type_signature);
1052
1053 QCdbus_type_array = intern (":array");
1054 staticpro (&QCdbus_type_array);
1055
1056 QCdbus_type_variant = intern (":variant");
1057 staticpro (&QCdbus_type_variant);
1058
1059 QCdbus_type_struct = intern (":struct");
1060 staticpro (&QCdbus_type_struct);
1061
1062 QCdbus_type_dict_entry = intern (":dict-entry");
1063 staticpro (&QCdbus_type_dict_entry);
1064
853 DEFVAR_LISP ("dbus-registered-functions-table", &Vdbus_registered_functions_table, 1065 DEFVAR_LISP ("dbus-registered-functions-table", &Vdbus_registered_functions_table,
854 doc: /* Hash table of registered functions for D-Bus. 1066 doc: /* Hash table of registered functions for D-Bus.
855The key in the hash table is the list (BUS INTERFACE MEMBER). BUS is 1067The key in the hash table is the list (BUS INTERFACE MEMBER). BUS is