#include "ProxySchemasGSettingsAccess.h" #include #include #include struct GSettingsList { const char * schemaName; GSettings* client; struct GSettingsList * next; }; struct GSettingsList * proxySchemas; int startsWith(const char *pre, const char *str) { size_t lenpre = strlen(pre), lenstr = strlen(str); return lenstr < lenpre ? 0 : strncmp(pre, str, lenpre) == 0; } __attribute__((constructor)) void init() { g_type_init(); proxySchemas = 0; const gchar* const* schemas = g_settings_list_schemas(); while (*schemas) { if (startsWith("org.gnome.system.proxy", (const char *)(*schemas))) { struct GSettingsList * nclients = (struct GSettingsList *) malloc(sizeof(struct GSettingsList)); nclients->next = proxySchemas; nclients->schemaName = *schemas; nclients->client = g_settings_new(*schemas); proxySchemas = nclients; } schemas++; } } __attribute__((destructor)) void destroy() { struct GSettingsList * proxySchemasIt = proxySchemas; while (proxySchemasIt != 0) { struct GSettingsList * next = proxySchemasIt->next; free(proxySchemasIt); proxySchemasIt = next; } proxySchemas = 0; } void convertKey(JNIEnv *env, jmethodID put, jobject hashMap, gchar* gkey, GSettings* schema, GVariant * gvalue) { jstring key = (*env)->NewStringUTF(env, gkey); jobject value = 0; const GVariantType * t = g_variant_get_type(gvalue); if (g_variant_type_equal(t, G_VARIANT_TYPE_STRING)) { const gchar * gstring = g_variant_get_string(gvalue, 0); value = (*env)->NewStringUTF(env, gstring); } else if (g_variant_type_equal(t, G_VARIANT_TYPE_BOOLEAN)) { jclass bClass = (*env)->FindClass(env, "java/lang/Boolean"); jmethodID valueOf = (*env)->GetStaticMethodID(env, bClass, "valueOf", "(Z)Ljava/lang/Boolean;"); value = (*env)->CallStaticObjectMethod(env, bClass, valueOf, g_variant_get_boolean(gvalue)); (*env)->DeleteLocalRef(env, bClass); } else if (g_variant_type_equal(t, G_VARIANT_TYPE_INT32)) { jclass bClass = (*env)->FindClass(env, "java/lang/Integer"); jmethodID valueOf = (*env)->GetStaticMethodID(env, bClass, "valueOf", "(I)Ljava/lang/Integer;"); value = (*env)->CallStaticObjectMethod(env, bClass, valueOf, g_variant_get_int32(gvalue)); (*env)->DeleteLocalRef(env, bClass); } else if (g_variant_type_equal(t, G_VARIANT_TYPE_STRING_ARRAY)) { int size = g_variant_n_children(gvalue); jclass bClass = (*env)->FindClass(env, "java/util/ArrayList"); jmethodID init = (*env)->GetMethodID(env, bClass, "", "(I)V"); jmethodID add = (*env)->GetMethodID(env, bClass, "add", "(Ljava/lang/Object;)Z"); value = (*env)->NewObject(env, bClass, init, size); int i; for (i = 0; i < size; i++) { GVariant * gsvalue = g_variant_get_child_value(gvalue, i); const gchar * gstring = g_variant_get_string(gsvalue, 0); jobject svalue = (*env)->NewStringUTF(env, gstring); (*env)->CallObjectMethod(env, value, add, svalue); (*env)->DeleteLocalRef(env, svalue); } (*env)->DeleteLocalRef(env, bClass); } if (value != 0) { (*env)->CallObjectMethod(env, hashMap, put, key, value); (*env)->DeleteLocalRef(env, value); } (*env)->DeleteLocalRef(env, key); } void convertSchema(JNIEnv *env, jclass mapClass, jmethodID init, jmethodID put, jobject hashMap, const char * schemaName, GSettings* schema) { jobject subHashMap = (*env)->NewObject(env, mapClass, init); jstring jschemaName = (*env)->NewStringUTF(env, schemaName); gchar** keys = g_settings_list_keys(schema); while (*keys) { convertKey(env, put, subHashMap, *keys, schema, g_settings_get_value(schema, *keys)); keys++; } (*env)->CallObjectMethod(env, hashMap, put, jschemaName, subHashMap); (*env)->DeleteLocalRef(env, subHashMap); (*env)->DeleteLocalRef(env, jschemaName); } JNIEXPORT jobject JNICALL Java_com_btr_proxy_search_desktop_gnome_ProxySchemasGSettingsAccess_getValueByKeyBySchema(JNIEnv *env, jclass c) { jclass mapClass = (*env)->FindClass(env, "java/util/HashMap"); jmethodID init = (*env)->GetMethodID(env, mapClass, "", "()V"); jobject hashMap = (*env)->NewObject(env, mapClass, init); jmethodID put = (*env)->GetMethodID(env, mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); struct GSettingsList * proxySchemasIt = proxySchemas; while (proxySchemasIt != 0) { convertSchema(env, mapClass, init, put, hashMap, proxySchemasIt->schemaName, proxySchemasIt->client); proxySchemasIt = proxySchemasIt->next; } (*env)->DeleteLocalRef(env, mapClass); return hashMap; }