/*
 * Java-Gnome Bindings Library
 *
 * Copyright 1998-2004 the Java-Gnome Team, all rights reserved.
 *
 * The Java-Gnome bindings library is free software distributed under
 * the terms of the GNU Library General Public License version 2.
 */

#include <jni.h>
#include <gconf/gconf.h>
#include <gconf/gconf-client.h>

#ifndef _Included_org_gnu_gconf_ConfClient
#define _Included_org_gnu_gconf_ConfClient
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_get_default
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1get_1default
  (JNIEnv *env, jclass cls)
{
	return (jint)gconf_client_get_default();
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_get_for_engine
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1get_1for_1engine
  (JNIEnv *env, jclass cls, jint engine)
{
	return (jint)gconf_client_get_for_engine((GConfEngine*)engine);
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_add_dir
 * Signature: (ILjava/lang/String;I[I)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1add_1dir
  (JNIEnv *env, jclass cls, jint client, jstring dir, jint preload, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, dir, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gconf_client_add_dir((GConfClient*)client, str, (GConfClientPreloadType)preload, &err);
	(*env)->ReleaseStringUTFChars(env, dir, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_remove_dir
 * Signature: (ILjava/lang/String;[I)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1remove_1dir
  (JNIEnv *env, jclass cls, jint client, jstring dir, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, dir, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gconf_client_remove_dir((GConfClient*)client, str, &err);
	(*env)->ReleaseStringUTFChars(env, dir, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
}

typedef struct 
{
	JNIEnv* env;
	jobject obj;
	jmethodID methodID;
	jstring namespace;
} NotifyData;

void notifyCallback(GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer data)
{
	NotifyData *nd = (NotifyData*)data;
	(*nd->env)->CallVoidMethod(nd->env, nd->obj, nd->methodID, (jint)entry, nd->namespace);
}

void notifyFree(gpointer data)
{
	g_free((NotifyData*)data);
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_notify_add
 * Signature: (ILjava/lang/String;[I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1notify_1add
  (JNIEnv *env, jobject obj, jint client, jstring namespace, jintArray exception)
{
	static jmethodID methodID = NULL;
	jclass cls = (*env)->GetObjectClass(env, obj);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, namespace, NULL);
	NotifyData *data;
	guint ret;
	if (methodID == NULL) {
		methodID = (*env)->GetMethodID(env, cls, "notifyCallback", "(ILjava/lang/String;)V");
		if (methodID == NULL)
			return -1;
	}
	data = g_new(NotifyData, 1);
	data->env = env;
	data->obj = obj;
	data->methodID = methodID;
	data->namespace = namespace;
	ret = gconf_client_notify_add((GConfClient*)client, str, notifyCallback, data, notifyFree, &err);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	(*env)->ReleaseStringUTFChars(env, namespace, str);
	return ret;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_notify_remove
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1notify_1remove
  (JNIEnv *env, jclass cls, jint client, jint cnxn)
{
	gconf_client_notify_remove((GConfClient*)client, (int)cnxn);
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_clear_cache
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1clear_1cache
  (JNIEnv *env, jclass cls, jint client)
{
	gconf_client_clear_cache((GConfClient*)client);
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_preload
 * Signature: (ILjava/lang/String;I[I)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1preload
  (JNIEnv *env, jclass cls, jint client, jstring dir, jint type, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, dir, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gconf_client_preload((GConfClient*)client, str, (GConfClientPreloadType)type, &err);
	(*env)->ReleaseStringUTFChars(env, dir, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_set
 * Signature: (ILjava/lang/String;I[I)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1set
  (JNIEnv *env, jclass cls, jint client, jstring key, jint val, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gconf_client_set((GConfClient*)client, str, (GConfValue*)val, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_get
 * Signature: (ILjava/lang/String;[I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1get
  (JNIEnv *env, jclass cls, jint client, jstring key, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	GConfValue* val = gconf_client_get((GConfClient*)client, str, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jint)val;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_get_without_default
 * Signature: (ILjava/lang/String;[I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1get_1without_1default
  (JNIEnv *env, jclass cls, jint client, jstring key, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	GConfValue* val = gconf_client_get_without_default((GConfClient*)client, str, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jint)val;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_get_entry
 * Signature: (ILjava/lang/String;Ljava/lang/String;Z[I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1get_1entry
  (JNIEnv *env, jclass cls, jint client, jstring key, jstring locale, jboolean schemaDefault, jintArray exception)
{
	gchar *str1 = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	gchar *str2 = (gchar*)(*env)->GetStringUTFChars(env, locale, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	GConfEntry* val = gconf_client_get_entry((GConfClient*)client, str1, str2, (gboolean)schemaDefault, &err);
	(*env)->ReleaseStringUTFChars(env, key, str1);
	(*env)->ReleaseStringUTFChars(env, locale, str2);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jint)val;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_get_default_from_schema
 * Signature: (ILjava/lang/String;[I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1get_1default_1from_1schema
  (JNIEnv *env, jclass cls, jint client, jstring key, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	GConfValue* val = gconf_client_get_default_from_schema((GConfClient*)client, str, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jint)val;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_unset
 * Signature: (ILjava/lang/String;[I)Z
 */
JNIEXPORT jboolean JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1unset
  (JNIEnv *env, jclass cls, jint client, jstring key, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gboolean val = gconf_client_unset((GConfClient*)client, str, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jboolean)val;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_all_entries
 * Signature: (ILjava/lang/String;[I)[I
 */
JNIEXPORT jintArray JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1all_1entries
  (JNIEnv *env, jclass cls, jint client, jstring dir, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, dir, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	GSList* val = gconf_client_all_entries((GConfClient*)client, str, &err);
	int i = 0;
	jintArray ar;
	guint len;
	if (NULL == val)
		return NULL;
	len = g_slist_length(val);
	ar = (*env)->NewIntArray(env, len);
	for (i = 0; i < len; i++) {
		GSList *item = g_slist_nth(val, i);
		(*env)->SetIntArrayRegion(env, ar, i, 1, (jint*)item->data);
	}
	(*env)->ReleaseStringUTFChars(env, dir, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return ar;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_all_dirs
 * Signature: (ILjava/lang/String;[I)jobjectArray
 */
JNIEXPORT jobjectArray JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1all_1dirs
  (JNIEnv *env, jclass cls, jint client, jstring dir, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, dir, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	GSList* val = gconf_client_all_dirs((GConfClient*)client, str, &err);
	int i = 0;
	guint len;
	jclass strCls;
	jobjectArray ar;
	if (NULL == val)
		return NULL;
	len = g_slist_length(val);
	strCls = (*env)->FindClass(env, "java/lang/String");
	if (NULL == strCls)
		return NULL;
	ar = (*env)->NewObjectArray(env, len, strCls, NULL);
	for (i = 0; i < len; i++) {
		GSList *item = g_slist_nth(val, i);
	 	jstring str = (*env)->NewStringUTF(env, (gchar*)item->data);
		(*env)->SetObjectArrayElement(env, ar, i, str);
	}
	(*env)->ReleaseStringUTFChars(env, dir, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return ar;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_suggest_sync
 * Signature: (I[I)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1suggest_1sync
  (JNIEnv *env, jclass cls, jint client, jintArray exception)
{
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gconf_client_suggest_sync((GConfClient*)client, &err);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_dir_exists
 * Signature: (ILjava/lang/String;[I)Z
 */
JNIEXPORT jboolean JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1dir_1exists
  (JNIEnv *env, jclass cls, jint client, jstring dir, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, dir, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gboolean val = gconf_client_dir_exists((GConfClient*)client, str, &err);
	(*env)->ReleaseStringUTFChars(env, dir, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jboolean)val;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_get_float
 * Signature: (ILjava/lang/String;[I)D
 */
JNIEXPORT jdouble JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1get_1float
  (JNIEnv *env, jclass cls, jint client, jstring key, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gdouble val = gconf_client_get_float((GConfClient*)client, str, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jdouble)val;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_get_int
 * Signature: (ILjava/lang/String;[I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1get_1int
  (JNIEnv *env, jclass cls, jint client, jstring key, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gint val = gconf_client_get_int((GConfClient*)client, str, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jint)val;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_get_string
 * Signature: (ILjava/lang/String;[I)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1get_1string
  (JNIEnv *env, jclass cls, jint client, jstring key, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError *err = NULL;
	gchar* val = gconf_client_get_string((GConfClient*)client, str, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	if (err != NULL) {
		(*env)->SetIntArrayRegion(env, exception, 0, 1, (jint*)err);
	}
	return (*env)->NewStringUTF(env, val);
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_get_bool
 * Signature: (ILjava/lang/String;[I)Z
 */
JNIEXPORT jboolean JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1get_1bool
  (JNIEnv *env, jclass cls, jint client, jstring key, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gboolean val = gconf_client_get_bool((GConfClient*)client, str, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jboolean)val;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_get_schema
 * Signature: (ILjava/lang/String;[I)I
 */
JNIEXPORT jint JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1get_1schema
  (JNIEnv *env, jclass cls, jint client, jstring key, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	GConfSchema* val = gconf_client_get_schema((GConfClient*)client, str, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jint)val;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_get_list
 * Signature: (ILjava/lang/String;I[I)Ljava/lang/Object;
 */
JNIEXPORT jobjectArray JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1get_1list
  (JNIEnv *env, jclass cls, jint client, jstring key, jint type, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	GConfValueType vt = (GConfValueType)type;
	GSList* val = gconf_client_get_list((GConfClient*)client, str, vt, &err);
	int i = 0;
	jclass aCls;
	guint len;
	jobjectArray ar;
	if (NULL == val)
		return NULL;
	len = g_slist_length(val);
	if (vt == GCONF_VALUE_STRING)
		aCls = (*env)->FindClass(env, "java/lang/String");
	else if (vt == GCONF_VALUE_INT)
		aCls = (*env)->FindClass(env, "java/lang/Integer");
	else if (vt == GCONF_VALUE_FLOAT)
		aCls = (*env)->FindClass(env, "java/lang/Double");
	else if (vt == GCONF_VALUE_BOOL)
		aCls = (*env)->FindClass(env, "java/lang/Boolean");
	else if (vt == GCONF_VALUE_SCHEMA)
		aCls = (*env)->FindClass(env, "org/gnu/gconf/ConfSchema");
	if (NULL == aCls)
		return NULL;
	ar = (*env)->NewObjectArray(env, len, aCls, NULL);
	for (i = 0; i < len; i++) {
		GSList *item = g_slist_nth(val, i);
		if (vt == GCONF_VALUE_STRING) {
			jstring str = (*env)->NewStringUTF(env, item->data);
			(*env)->SetObjectArrayElement(env, ar, i, str);
		} else if (vt == GCONF_VALUE_INT) {
			jmethodID mid = (*env)->GetMethodID(env, aCls, "<init>", "(I)V");
			jobject obj;
			if (mid == NULL)
				return NULL;
			obj = (*env)->NewObject(env, aCls, mid, (jint)item->data);
			(*env)->SetObjectArrayElement(env, ar, i, obj);
		} else if (vt == GCONF_VALUE_FLOAT) {
			jmethodID mid = (*env)->GetMethodID(env, aCls, "<init>", "(D)V");
			jobject obj;
			if (mid == NULL)
				return NULL;
			obj = (*env)->NewObject(env, aCls, mid, (jdouble*)item->data);
			(*env)->SetObjectArrayElement(env, ar, i, obj);
		} else if (vt == GCONF_VALUE_BOOL) {
			jmethodID mid = (*env)->GetMethodID(env, aCls, "<init>", "(Z)V");
			jobject obj;
			if (mid == NULL)
				return NULL;
			obj = (*env)->NewObject(env, aCls, mid, (jboolean)((gboolean)item->data));
			(*env)->SetObjectArrayElement(env, ar, i, obj);
		} else if (vt == GCONF_VALUE_SCHEMA) {
			jmethodID mid = (*env)->GetMethodID(env, aCls, "<init>", "(I)V");
			jobject obj;
			if (mid == NULL)
				return NULL;
			obj = (*env)->NewObject(env, aCls, mid, (jint)item->data);
			(*env)->SetObjectArrayElement(env, ar, i, obj);
		}
	}
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return ar;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_get_pair
 * Signature: (ILjava/lang/String;II[I[I[I)Z
 */
JNIEXPORT jboolean JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1get_1pair
  (JNIEnv *env, jclass cls, jint client, jstring key, jint carType, jint cdrType, jintArray car, jintArray cdr, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gpointer carloc = (gpointer)(*env)->GetIntArrayElements(env, car, NULL);
	gpointer cdrloc = (gpointer)(*env)->GetIntArrayElements(env, cdr, NULL);
	gboolean val = gconf_client_get_pair((GConfClient*)client, str, (GConfValueType)carType, 
			(GConfValueType)cdrType, carloc, cdrloc, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	(*env)->ReleaseIntArrayElements(env, car, (jint*)carloc, 0);
	(*env)->ReleaseIntArrayElements(env, cdr, (jint*)cdrloc, 0);
	return (jboolean)val;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_set_float
 * Signature: (ILjava/lang/String;D[I)Z
 */
JNIEXPORT jboolean JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1set_1float
  (JNIEnv *env, jclass cls, jint client, jstring key, jdouble val, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gboolean ret = gconf_client_set_float((GConfClient*)client, str, (gdouble)val, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jboolean)ret;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_set_int
 * Signature: (ILjava/lang/String;I[I)Z
 */
JNIEXPORT jboolean JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1set_1int
  (JNIEnv *env, jclass cls, jint client, jstring key, jint val, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gboolean ret = gconf_client_set_int((GConfClient*)client, str, (gint)val, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jboolean)ret;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_set_string
 * Signature: (ILjava/lang/String;Ljava/lang/String;[I)Z
 */
JNIEXPORT jboolean JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1set_1string
  (JNIEnv *env, jclass cls, jint client, jstring key, jstring val, jintArray exception)
{
	gchar *str1 = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	gchar *str2 = (gchar*)(*env)->GetStringUTFChars(env, val, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gboolean ret = gconf_client_set_string((GConfClient*)client, str1, str2, &err);
	(*env)->ReleaseStringUTFChars(env, key, str1);
	(*env)->ReleaseStringUTFChars(env, key, str2);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jboolean)ret;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_set_bool
 * Signature: (ILjava/lang/String;Z[I)Z
 */
JNIEXPORT jboolean JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1set_1bool
  (JNIEnv *env, jclass cls, jint client, jstring key, jboolean val, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gboolean ret = gconf_client_set_bool((GConfClient*)client, str, (gboolean)val, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jboolean)ret;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_set_schema
 * Signature: (ILjava/lang/String;I[I)Z
 */
JNIEXPORT jboolean JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1set_1schema
  (JNIEnv *env, jclass cls, jint client, jstring key, jint val, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gboolean ret = gconf_client_set_schema((GConfClient*)client, str, (GConfSchema*)val, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jboolean)ret;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_set_list
 * Signature: (ILjava/lang/String;I[Ljava/lang/Object;[I)Z
 */
JNIEXPORT jboolean JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1set_1list
  (JNIEnv *env, jclass cls, jint client, jstring key, jint type, jobjectArray list, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	GConfValueType vt = (GConfValueType)type;
	int i = 0;
	jclass aCls = NULL;
	jobject obj;
	jfieldID fid;
	jmethodID mid;
	jsize len;
	GSList* gslist;
	gpointer data = NULL;
	gboolean ret;
	
	len = (*env)->GetArrayLength(env, list);
	gslist = g_slist_alloc();
	for (i = 0; i < len; i++) {
		obj = (*env)->GetObjectArrayElement(env, list, i);
		if (vt == GCONF_VALUE_STRING) {
			jstring value = (jstring)obj;
			const gchar* v = (*env)->GetStringUTFChars(env, value, NULL);
			data = (gpointer)v;
		}
		else if (vt == GCONF_VALUE_INT) {
			jint value;
			aCls = (*env)->FindClass(env, "java/lang/Integer");
			mid = (*env)->GetMethodID(env, cls, "intValue", "()I");
			if (NULL == mid)
				return (jboolean)JNI_FALSE;
			value = (*env)->CallIntMethod(env, obj, mid);
			data = (gpointer)&value;
		}
		else if (vt == GCONF_VALUE_FLOAT) {
			jdouble value;
			aCls = (*env)->FindClass(env, "java/lang/Double");
			mid = (*env)->GetMethodID(env, cls, "doubleValue", "()D");
			if (NULL == mid)
				return (jboolean)JNI_FALSE;
			value = (*env)->CallDoubleMethod(env, obj, mid);
			data = (gpointer)&value;
		}
		else if (vt == GCONF_VALUE_BOOL) {
			jboolean value;
			aCls = (*env)->FindClass(env, "java/lang/Boolean");
			mid = (*env)->GetMethodID(env, cls, "booleanValue", "()Z");
			if (NULL == mid)
				return (jboolean)JNI_FALSE;
			value = (*env)->CallBooleanMethod(env, obj, mid);
			data = (gpointer)&value;
		}
		else if (vt == GCONF_VALUE_SCHEMA) {
			jint value;
			aCls = (*env)->FindClass(env, "org/gnu/gconf/ConfSchema");
			fid = (*env)->GetFieldID(env, aCls, "handle", "I");
			if (fid == NULL)
				return (jboolean)JNI_FALSE;
			value = (jint)(*env)->GetObjectField(env, obj, fid);
			data = (gpointer)value;
		}
		gslist = g_slist_append(gslist, data);
	}
	ret = gconf_client_set_list((GConfClient*)client, str, vt, gslist, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jboolean)ret;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_set_pair
 * Signature: (ILjava/lang/String;IIII[I)Z
 */
JNIEXPORT jboolean JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1set_1pair
  (JNIEnv *env, jclass cls, jint client, jstring key, jint carType, jint cdrType, jint car, jint cdr, jintArray exception)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	GError* err = (GError*)(*env)->GetIntArrayElements(env, exception, NULL);
	gboolean ret = gconf_client_set_pair((GConfClient*)client, str, (GConfValueType)carType, 
			(GConfValueType)cdrType, (gconstpointer)car, (gconstpointer)cdr, &err);
	(*env)->ReleaseStringUTFChars(env, key, str);
	(*env)->ReleaseIntArrayElements(env, exception, (jint*)err, 0);
	return (jboolean)ret;
}

/*
 * Class:     org_gnu_gconf_ConfClient
 * Method:    gconf_client_value_changed
 * Signature: (ILjava/lang/String;I)V
 */
JNIEXPORT void JNICALL Java_org_gnu_gconf_ConfClient_gconf_1client_1value_1changed
  (JNIEnv *env, jclass cls, jint client, jstring key, jint value)
{
	gchar *str = (gchar*)(*env)->GetStringUTFChars(env, key, NULL);
	gconf_client_value_changed((GConfClient*)client, str, (GConfValue*)value);
	(*env)->ReleaseStringUTFChars(env, key, str);
}

#ifdef __cplusplus
}
#endif
#endif
