void handle_signal_callback(gpointer no_used_key, struct SignalInfo* info, DBusMessage *msg) { DBusMessageIter iter; dbus_message_iter_init(msg, &iter); int num = g_slist_length(info->signatures); JSValueRef *params = g_new(JSValueRef, num); for (int i=0; i<num; i++) { params[i] = dbus_to_js(get_global_context(), &iter); if (!dbus_message_iter_next(&iter)) { } } g_assert(info->callback != NULL); JSObjectCallAsFunction(get_global_context(), info->callback, NULL, num, params, NULL); g_free(params); }
DBusHandlerResult watch_signal(DBusConnection* connection, DBusMessage *msg, void *no_use) { if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; const char* iface = dbus_message_get_interface(msg); const char* s_name = dbus_message_get_member(msg); const char* path = dbus_message_get_path(msg); char* key = g_strdup_printf("%s%s%s", path, iface, s_name); struct SignalInfo* info = g_hash_table_lookup(__sig_info_hash, key); g_free(key); if (info == NULL) { return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } else { DBusMessageIter iter; dbus_message_iter_init(msg, &iter); int num = g_slist_length(info->signatures); JSValueRef *params = g_new(JSValueRef, num); for (int i=0; i<num; i++) { params[i] = dbus_to_js(get_global_context(), &iter); if (!dbus_message_iter_next(&iter)) { } } g_assert(info->callback != NULL); JSObjectCallAsFunction(get_global_context(), info->callback, NULL, num, params, NULL); g_free(params); return DBUS_HANDLER_RESULT_HANDLED; } }
JSValueRef dbus_to_js(JSContextRef ctx, GVariant *dbus) { JSValueRef jsvalue = NULL; GVariantClass type = g_variant_classify(dbus); switch (type) { case G_VARIANT_CLASS_STRING: case G_VARIANT_CLASS_OBJECT_PATH: case G_VARIANT_CLASS_SIGNATURE: { JSStringRef js_string = JSStringCreateWithUTF8CString(g_variant_get_string(dbus, NULL)); jsvalue = JSValueMakeString(ctx, js_string); JSStringRelease(js_string); return jsvalue; } case G_VARIANT_CLASS_BYTE: return JSValueMakeNumber(ctx, g_variant_get_byte(dbus)); case G_VARIANT_CLASS_DOUBLE: return JSValueMakeNumber(ctx, g_variant_get_double(dbus)); case G_VARIANT_CLASS_INT16: return JSValueMakeNumber(ctx, g_variant_get_int16(dbus)); case G_VARIANT_CLASS_UINT16: return JSValueMakeNumber(ctx, g_variant_get_uint16(dbus)); case G_VARIANT_CLASS_INT32: return JSValueMakeNumber(ctx, g_variant_get_int32(dbus)); case G_VARIANT_CLASS_UINT32: return JSValueMakeNumber(ctx, g_variant_get_uint32(dbus)); case G_VARIANT_CLASS_INT64: return JSValueMakeNumber(ctx, g_variant_get_int64(dbus)); case G_VARIANT_CLASS_UINT64: return JSValueMakeNumber(ctx, g_variant_get_uint64(dbus)); case G_VARIANT_CLASS_BOOLEAN: return JSValueMakeBoolean(ctx, g_variant_get_boolean(dbus)); case G_VARIANT_CLASS_HANDLE: g_warning("didn't support FD type"); return JSValueMakeNumber(ctx, g_variant_get_uint32(dbus)); case G_VARIANT_CLASS_VARIANT: { GVariant* v = g_variant_get_variant(dbus); jsvalue = dbus_to_js(ctx, v); g_variant_unref(v); return jsvalue; } case G_VARIANT_CLASS_DICT_ENTRY: /*g_assert_not_reached();*/ break; case G_VARIANT_CLASS_ARRAY: { if (g_variant_type_is_dict_entry(g_variant_type_element(g_variant_get_type(dbus)))) { jsvalue = JSObjectMake(ctx, NULL, NULL); for (size_t i=0; i<g_variant_n_children(dbus); i++) { GVariant *dic = g_variant_get_child_value(dbus, i); GVariant *key= g_variant_get_child_value (dic, 0); GVariant *value = g_variant_get_child_value (dic, 1); JSValueRef js_key = dbus_to_js(ctx, key); JSValueRef js_value = dbus_to_js(ctx, value); JSStringRef key_str = JSValueToStringCopy(ctx, js_key, NULL); JSObjectSetProperty(ctx, (JSObjectRef)jsvalue, key_str, js_value, 0, NULL); JSStringRelease(key_str); g_variant_unref(key); g_variant_unref(value); g_variant_unref(dic); } return jsvalue; } else { int n = g_variant_n_children(dbus); JSValueRef *args = g_new(JSValueRef, n); for (int i=0; i < n; i++) { GVariant* v = g_variant_get_child_value(dbus, i); args[i] = dbus_to_js(ctx, v); g_variant_unref(v); } jsvalue = JSObjectMakeArray(ctx, n, args, NULL); g_free(args); return jsvalue; } } case G_VARIANT_CLASS_TUPLE: { int n = g_variant_n_children(dbus); jsvalue = JSObjectMakeArray(ctx, 0, NULL, NULL); for (int i=0; i < n; i++) { GVariant* v = g_variant_get_child_value(dbus, i); JSObjectSetPropertyAtIndex(ctx, (JSObjectRef)jsvalue, i, dbus_to_js(ctx, v), NULL); g_variant_unref(v); } return jsvalue; } case G_VARIANT_CLASS_MAYBE: g_assert_not_reached(); } g_warning("didn't support signature type:%c", type); return JSValueMakeUndefined(ctx); }