2 * Browser D-Bus Bridge, JavaScriptCore version
4 * Copyright © 2008 Movial Creative Technologies Inc
5 * Contact: Movial Creative Technologies Inc, <info@movial.com>
6 * Authors: Kalle Vahlman, <kalle.vahlman@movial.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
26 #include <dbus/dbus.h>
27 #include <JavaScriptCore/JavaScript.h>
29 #include "jscorebus-marshal.h"
30 #include "jscorebus-method.h"
31 #include "jscorebus-signal.h"
34 static DBusConnection *session;
35 static DBusConnection *system;
38 /* Getters for the bus type properties */
40 JSValueRef _get_bus_type (JSContextRef context,
42 JSStringRef propertyName,
43 JSValueRef *exception)
45 if (JSStringIsEqualToUTF8CString(propertyName, "SESSION"))
47 return JSValueMakeNumber(context, DBUS_BUS_SESSION);
49 if (JSStringIsEqualToUTF8CString(propertyName, "SYSTEM"))
51 return JSValueMakeNumber(context, DBUS_BUS_SYSTEM);
54 return JSValueMakeUndefined(context);
59 JSStaticValue dbus_jsclass_staticvalues[] =
61 { "SESSION", _get_bus_type, NULL, kJSPropertyAttributeReadOnly },
62 { "SYSTEM", _get_bus_type, NULL, kJSPropertyAttributeReadOnly },
63 { NULL, NULL, NULL, 0 }
67 void _number_finalize (JSObjectRef object)
69 g_free(JSObjectGetPrivate(object));
73 JSValueRef _get_number_object (JSContextRef context,
75 JSObjectRef thisObject,
77 const JSValueRef arguments[],
78 JSValueRef *exception,
79 JSClassRef number_class)
83 if (argumentCount != 1)
85 /* TODO: set exception */
86 return JSValueMakeUndefined(context);
89 /* dbus_uint64_t should be large enough to hold any number so we just
90 * carry the value in private data as a pointer to dbus_uint64_t.
91 * The object class tells us later which type it is.
93 value = g_new0(dbus_uint64_t, 1);
94 *value = (dbus_uint64_t)JSValueToNumber(context, arguments[0], NULL);
96 return JSObjectMake(context, number_class, value);
99 JSValueRef _convert_number_object(JSContextRef context,
102 JSValueRef* exception)
104 /* FIXME: this isn't called at all... */
105 g_debug("%s(%p to %d)", __FUNCTION__, object, type);
111 dbus_uint64_t value = jsvalue_to_number_value(context, object, NULL);
112 return JSValueMakeNumber(context, (double)value);
119 dbus_uint64_t value = jsvalue_to_number_value(context, object, NULL);
120 str = g_strdup_printf("%llu", value);
121 jsstr = JSStringCreateWithUTF8CString(str);
123 jsvalue = JSValueMakeString(context, jsstr);
124 JSStringRelease(jsstr);
134 #define MAKE_NUMBER_CLASS_AND_GETTER(classname, shortname) \
135 static const JSClassDefinition shortname ##_jsclass_def = \
137 0, kJSClassAttributeNone, classname, \
138 NULL, NULL, NULL, NULL, _number_finalize, NULL, NULL, \
139 NULL, NULL, NULL, NULL, NULL, NULL, _convert_number_object \
142 static JSValueRef _get_ ##shortname (JSContextRef context, \
143 JSObjectRef function, \
144 JSObjectRef thisObject, \
145 size_t argumentCount, \
146 const JSValueRef arguments[], \
147 JSValueRef *exception) \
149 return _get_number_object(context, function, thisObject, \
150 argumentCount, arguments, exception, \
151 (JSClassRef)jsclass_lookup(&shortname ##_jsclass_def)); \
154 MAKE_NUMBER_CLASS_AND_GETTER("DBusUInt32", uint32)
155 MAKE_NUMBER_CLASS_AND_GETTER("DBusInt32", int32)
156 MAKE_NUMBER_CLASS_AND_GETTER("DBusDouble", double)
157 MAKE_NUMBER_CLASS_AND_GETTER("DBusByte", byte)
158 MAKE_NUMBER_CLASS_AND_GETTER("DBusUInt64", uint64)
159 MAKE_NUMBER_CLASS_AND_GETTER("DBusInt64", int64)
160 MAKE_NUMBER_CLASS_AND_GETTER("DBusUInt16", uint16)
161 MAKE_NUMBER_CLASS_AND_GETTER("DBusInt16", int16)
163 static const JSClassDefinition variant_jsclass_def =
165 0, kJSClassAttributeNone, "DBusVariant",
166 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
167 NULL, NULL, NULL, NULL, NULL, NULL, NULL
171 JSValueRef _construct_variant (JSContextRef context,
172 JSObjectRef function,
173 JSObjectRef thisObject,
174 size_t argumentCount,
175 const JSValueRef arguments[],
176 JSValueRef *exception)
179 if (argumentCount != 1)
181 /* TODO: set exception */
182 return JSValueMakeUndefined(context);
185 /* Just carry the value in private data */
186 return JSObjectMake(context, (JSClassRef)jsclass_lookup(&variant_jsclass_def), (void*)arguments[0]);
189 static const JSClassDefinition struct_jsclass_def =
191 0, kJSClassAttributeNone, "DBusStruct",
192 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
193 NULL, NULL, NULL, NULL, NULL, NULL, NULL
197 JSValueRef _construct_struct (JSContextRef context,
198 JSObjectRef function,
199 JSObjectRef thisObject,
200 size_t argumentCount,
201 const JSValueRef arguments[],
202 JSValueRef *exception)
204 if (argumentCount != 1)
206 /* TODO: set exception */
207 return JSValueMakeUndefined(context);
210 /* Just carry the object in private data */
211 return JSObjectMake(context,
212 (JSClassRef)jsclass_lookup(&struct_jsclass_def),
213 (void*)arguments[0]);
216 static const JSClassDefinition object_path_jsclass_def =
218 0, kJSClassAttributeNone, "DBusObjectPath",
219 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
220 NULL, NULL, NULL, NULL, NULL, NULL, NULL
224 gboolean is_valid_path (const char *path)
226 const char *this = path;
227 const char *prev = this;
229 if (strlen(path) == 0)
232 /* MUST begin with zero */
236 /* The path is guranteed to be null-terminated */
237 while (*this != '\0')
239 /* Two slashes can't be together */
240 if (*this == '/' && *prev == '/')
243 } else if (!(((*this) >= '0' && (*this) <= '9') ||
244 ((*this) >= 'A' && (*this) <= 'Z') ||
245 ((*this) >= 'a' && (*this) <= 'z') ||
246 (*this) == '_' || (*this) == '/')) {
257 JSValueRef _construct_object_path (JSContextRef context,
258 JSObjectRef function,
259 JSObjectRef thisObject,
260 size_t argumentCount,
261 const JSValueRef arguments[],
262 JSValueRef *exception)
266 if (argumentCount != 1)
268 /* TODO: set exception */
269 return JSValueMakeUndefined(context);
272 /* D-Bus doesn't like invalid object paths _at all_, so instead of risking
273 * disconnection, we'll validate the path now.
275 path = string_from_jsvalue(context, arguments[0]);
276 if (!is_valid_path(path))
278 g_free((gpointer)path);
279 /* TODO: set exception */
280 return JSValueMakeUndefined(context);
282 g_free((gpointer)path);
284 /* Just carry the value in private data */
285 return JSObjectMake(context,
286 (JSClassRef)jsclass_lookup(&object_path_jsclass_def),
287 (void*)arguments[0]);
290 static const JSClassDefinition signature_jsclass_def =
292 0, kJSClassAttributeNone, "DBusSignature",
293 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
294 NULL, NULL, NULL, NULL, NULL, NULL, NULL
298 JSValueRef _construct_signature (JSContextRef context,
299 JSObjectRef function,
300 JSObjectRef thisObject,
301 size_t argumentCount,
302 const JSValueRef arguments[],
303 JSValueRef *exception)
305 if (argumentCount != 1)
307 /* TODO: set exception */
308 return JSValueMakeUndefined(context);
311 /* Just carry the value in private data */
312 return JSObjectMake(context,
313 (JSClassRef)jsclass_lookup(&signature_jsclass_def),
314 (void*)arguments[0]);
318 JSValueRef getMethod (JSContextRef context,
319 JSObjectRef function,
320 JSObjectRef thisObject,
321 size_t argumentCount,
322 const JSValueRef arguments[],
323 JSValueRef *exception)
325 JSGlobalContextRef global_context = JSObjectGetPrivate(thisObject);
327 if (argumentCount < 4)
329 /* TODO: set exception */
330 return JSValueMakeUndefined(context);
333 return jscorebus_create_method(global_context,
334 JSValueToNumber(context, arguments[0], NULL)
335 == DBUS_BUS_SYSTEM ? system : session,
336 string_from_jsvalue(context, arguments[1]),
337 string_from_jsvalue(context, arguments[2]),
338 string_from_jsvalue(context, arguments[3]),
340 string_from_jsvalue(context, arguments[4])
343 string_from_jsvalue(context, arguments[5])
346 JSValueToObject(context, arguments[6], NULL)
352 JSValueRef getSignal (JSContextRef context,
353 JSObjectRef function,
354 JSObjectRef thisObject,
355 size_t argumentCount,
356 const JSValueRef arguments[],
357 JSValueRef *exception)
359 JSGlobalContextRef global_context = JSObjectGetPrivate(thisObject);
361 if (argumentCount < 3)
363 /* TODO: set exception */
364 return JSValueMakeUndefined(context);
367 return jscorebus_create_signal(global_context,
368 JSValueToNumber(context, arguments[0], NULL)
369 == DBUS_BUS_SYSTEM ? system : session,
370 string_from_jsvalue(context, arguments[1]),
371 string_from_jsvalue(context, arguments[2]),
373 string_from_jsvalue(context, arguments[3])
376 string_from_jsvalue(context, arguments[4])
379 JSValueToObject(context, arguments[5], NULL)
385 void dbus_finalize(JSObjectRef object)
388 JSObjectSetPrivate(object, NULL);
392 JSStaticFunction dbus_jsclass_staticfuncs[] =
394 /* Type constructors */
395 { "Int32", _get_int32, kJSPropertyAttributeReadOnly },
396 { "UInt32", _get_uint32, kJSPropertyAttributeReadOnly },
397 { "Double", _get_double, kJSPropertyAttributeReadOnly },
398 { "Byte", _get_byte, kJSPropertyAttributeReadOnly },
399 { "Int64", _get_int64, kJSPropertyAttributeReadOnly },
400 { "UInt64", _get_uint64, kJSPropertyAttributeReadOnly },
401 { "Int16", _get_int16, kJSPropertyAttributeReadOnly },
402 { "UInt16", _get_uint16, kJSPropertyAttributeReadOnly },
403 { "ObjectPath", _construct_object_path, kJSPropertyAttributeReadOnly },
404 { "Signature", _construct_signature, kJSPropertyAttributeReadOnly },
405 { "Variant", _construct_variant, kJSPropertyAttributeReadOnly },
406 { "Struct", _construct_struct, kJSPropertyAttributeReadOnly },
409 { "getMethod", getMethod, kJSPropertyAttributeReadOnly },
410 { "getSignal", getSignal, kJSPropertyAttributeReadOnly },
416 JSClassDefinition dbus_jsclass_def =
419 kJSClassAttributeNone,
423 dbus_jsclass_staticvalues,
424 dbus_jsclass_staticfuncs,
445 void jscorebus_init(DBusConnection *psession, DBusConnection *psystem)
450 #define INIT_NUMBER_CLASS(name, def, type, num) \
451 jsclassdef_insert(name, def); \
452 jscorebus_number_class_names[num] = name; \
453 jscorebus_number_class_types[num] = type;
455 INIT_NUMBER_CLASS("DBusInt32", &int32_jsclass_def, DBUS_TYPE_INT32, 0);
456 INIT_NUMBER_CLASS("DBusUInt32", &uint32_jsclass_def, DBUS_TYPE_UINT32, 1);
457 INIT_NUMBER_CLASS("DBusDouble", &double_jsclass_def, DBUS_TYPE_DOUBLE, 2);
458 INIT_NUMBER_CLASS("DBusByte", &byte_jsclass_def, DBUS_TYPE_BYTE, 3);
459 INIT_NUMBER_CLASS("DBusUInt64", &uint64_jsclass_def, DBUS_TYPE_UINT64, 4);
460 INIT_NUMBER_CLASS("DBusInt64", &int64_jsclass_def, DBUS_TYPE_INT64, 5);
461 INIT_NUMBER_CLASS("DBusUInt16", &uint16_jsclass_def, DBUS_TYPE_UINT16, 6);
462 INIT_NUMBER_CLASS("DBusInt16", &int16_jsclass_def, DBUS_TYPE_INT16, 7);
464 jsclassdef_insert("DBusObjectPath", &object_path_jsclass_def);
465 jsclassdef_insert("DBusSignature", &signature_jsclass_def);
467 jsclassdef_insert("DBusVariant", &variant_jsclass_def);
468 jsclassdef_insert("DBusStruct", &struct_jsclass_def);
472 void jscorebus_export(JSGlobalContextRef context)
474 JSObjectRef globalObject;
477 JSClassRef dbus_jsclass;
479 // global_context = context;
481 dbus_jsclass = JSClassCreate(&dbus_jsclass_def);
482 dbus = JSObjectMake(context, dbus_jsclass, context);
484 globalObject = JSContextGetGlobalObject(context);
485 jsstr = JSStringCreateWithUTF8CString("DBus");
486 JSObjectSetProperty(context, globalObject,
488 kJSPropertyAttributeNone, NULL);