summaryrefslogtreecommitdiffstats
path: root/src_native/gnome/ProxySchemasGSettingsAccess.c
diff options
context:
space:
mode:
Diffstat (limited to 'src_native/gnome/ProxySchemasGSettingsAccess.c')
-rw-r--r--src_native/gnome/ProxySchemasGSettingsAccess.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/src_native/gnome/ProxySchemasGSettingsAccess.c b/src_native/gnome/ProxySchemasGSettingsAccess.c
new file mode 100644
index 0000000..b6e08a9
--- /dev/null
+++ b/src_native/gnome/ProxySchemasGSettingsAccess.c
@@ -0,0 +1,117 @@
+#include "ProxySchemasGSettingsAccess.h"
+#include <gio/gio.h>
+#include <string.h>
+#include <stdlib.h>
+
+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, "<init>", "(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, "<init>", "()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;
+}
+