libgaim/plugins/mono/loader/mono-helper.c

branch
cpw.khc.msnp14
changeset 20472
6a6d2ef151e6
parent 11996
858bd928831c
parent 14254
77edc7a6191a
child 20471
1966704b3e42
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgaim/plugins/mono/loader/mono-helper.c	Sun Apr 15 02:10:37 2007 +0000
@@ -0,0 +1,251 @@
+/*
+ * Mono Plugin Loader
+ *
+ * -- Thanks to the perl plugin loader for all the great tips ;-)
+ *
+ * Eoin Coffey
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <string.h>
+#include "mono-helper.h"
+#include "mono-glue.h"
+#include "value.h"
+#include "debug.h"
+
+static gboolean _runtime_active = FALSE;
+
+gboolean ml_init()
+{
+	MonoDomain *d;
+	
+	g_return_val_if_fail(_runtime_active == FALSE, TRUE);
+	
+	d = mono_jit_init("gaim");
+	
+	if (!d) {
+		ml_set_domain(NULL);
+		return FALSE;
+	}
+	
+	ml_set_domain(d);
+	
+	ml_init_internal_calls();
+	
+	_runtime_active = TRUE;
+	
+	return TRUE;
+}
+
+void ml_uninit()
+{
+	g_return_if_fail(_runtime_active == TRUE);
+	
+	mono_jit_cleanup(ml_get_domain());
+	
+	ml_set_domain(NULL);
+	
+	_runtime_active = FALSE;
+}
+
+MonoObject* ml_delegate_invoke(MonoObject *method, void **params)
+{
+	MonoObject *ret, *exception;
+	
+	ret = mono_runtime_delegate_invoke(method, params, &exception);
+	if (exception) {
+		gaim_debug(GAIM_DEBUG_ERROR, "mono", "caught exception: %s\n", mono_class_get_name(mono_object_get_class(exception)));
+	}
+	
+	return ret;
+}
+
+MonoObject* ml_invoke(MonoMethod *method, void *obj, void **params)
+{
+	MonoObject *ret, *exception;
+	
+	ret = mono_runtime_invoke(method, obj, params, &exception);
+	if (exception) {
+		gaim_debug(GAIM_DEBUG_ERROR, "mono", "caught exception: %s\n", mono_class_get_name(mono_object_get_class(exception)));
+	}
+	
+	return ret;
+}
+
+MonoClass* ml_find_plugin_class(MonoImage *image)
+{
+	MonoClass *klass, *pklass = NULL;
+	int i, total;
+
+	total = mono_image_get_table_rows (image, MONO_TABLE_TYPEDEF);
+	for (i = 1; i <= total; ++i) {
+		klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | i);
+		pklass = mono_class_get_parent(klass);
+		if (pklass) 
+			if (strcmp("GaimPlugin", mono_class_get_name(pklass)) == 0)
+				return klass;
+	}
+	
+	return NULL;
+}
+
+void ml_set_prop_string(MonoObject *obj, char *field, char *data)
+{
+	MonoClass *klass;
+	MonoProperty *prop;
+	MonoString *str;
+	gpointer args[1];
+	
+	klass = mono_object_get_class(obj);
+	
+	prop = mono_class_get_property_from_name(klass, field);
+	
+	str = mono_string_new(ml_get_domain(), data);
+	
+	args[0] = str;
+	
+	mono_property_set_value(prop, obj, args, NULL);
+}
+
+gchar* ml_get_prop_string(MonoObject *obj, char *field)
+{
+	MonoClass *klass;
+	MonoProperty *prop;
+	MonoString *str;
+	
+	klass = mono_object_get_class(obj);
+	
+	prop = mono_class_get_property_from_name(klass, field);
+	
+	str = (MonoString*)mono_property_get_value(prop, obj, NULL, NULL);
+	
+	return mono_string_to_utf8(str);
+}
+
+gboolean ml_is_api_dll(MonoImage *image)
+{	
+	MonoClass *klass;
+	int i, total;
+
+	total = mono_image_get_table_rows (image, MONO_TABLE_TYPEDEF);
+	for (i = 1; i <= total; ++i) {
+		klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | i);
+		if (strcmp(mono_class_get_name(klass), "Debug") == 0)
+			if (strcmp(mono_class_get_namespace(klass), "Gaim") == 0) {
+				ml_set_api_image(image);
+				return TRUE;
+			}
+	}
+	
+	return FALSE;
+}
+
+MonoObject* ml_object_from_gaim_type(GaimType type, gpointer data)
+{
+	return NULL;
+}
+
+MonoObject* ml_object_from_gaim_subtype(GaimSubType type, gpointer data)
+{
+	MonoObject *obj = NULL;
+	
+	switch (type) {
+		case GAIM_SUBTYPE_BLIST_BUDDY:
+			obj = gaim_blist_build_buddy_object(data);
+		break;
+		case GAIM_SUBTYPE_STATUS:
+			obj = gaim_status_build_status_object(data);
+		break;
+		default:
+		break;
+	}
+	
+	return obj;
+}
+
+MonoObject* ml_create_api_object(char *class_name)
+{
+	MonoObject *obj = NULL;
+	MonoClass *klass = NULL;
+		
+	klass = mono_class_from_name(ml_get_api_image(), "Gaim", class_name);
+	if (!klass) {
+		gaim_debug(GAIM_DEBUG_FATAL, "mono", "couldn't find the '%s' class\n", class_name);
+		return NULL;
+	}
+	
+	obj = mono_object_new(ml_get_domain(), klass);
+	if (!obj) {
+		gaim_debug(GAIM_DEBUG_FATAL, "mono", "couldn't create the object from class '%s'\n", class_name);
+		return NULL;
+	}
+	
+	mono_runtime_object_init(obj);
+	
+	return obj;
+}
+
+static MonoDomain *_domain = NULL;
+
+MonoDomain* ml_get_domain(void)
+{
+	return _domain;
+}
+
+void ml_set_domain(MonoDomain *d)
+{
+	_domain = d;
+}
+
+static MonoImage *_api_image = NULL;
+
+void ml_set_api_image(MonoImage *image)
+{
+	_api_image = image;
+}
+
+MonoImage* ml_get_api_image()
+{
+	return _api_image;
+}
+
+void ml_init_internal_calls(void)
+{
+	mono_add_internal_call("Gaim.Debug::_debug", gaim_debug_glue);
+	mono_add_internal_call("Gaim.Signal::_connect", gaim_signal_connect_glue);
+	mono_add_internal_call("Gaim.BuddyList::_get_handle", gaim_blist_get_handle_glue);
+}
+
+static GHashTable *plugins_hash = NULL;
+
+void ml_add_plugin(GaimMonoPlugin *plugin)
+{
+	if (!plugins_hash)
+		plugins_hash = g_hash_table_new(NULL, NULL);
+		
+	g_hash_table_insert(plugins_hash, plugin->klass, plugin);
+}
+
+gboolean ml_remove_plugin(GaimMonoPlugin *plugin)
+{
+	return g_hash_table_remove(plugins_hash, plugin->klass);
+}
+
+gpointer ml_find_plugin(GaimMonoPlugin *plugin)
+{
+	return g_hash_table_lookup(plugins_hash, plugin->klass);
+}
+
+gpointer ml_find_plugin_by_class(MonoClass *klass)
+{
+	return g_hash_table_lookup(plugins_hash, klass);
+}
+
+GHashTable* ml_get_plugin_hash()
+{
+	return plugins_hash;
+}

mercurial