Sat, 24 Mar 2007 06:24:59 +0000
SF Patch #1686400 from Eoin Coffey ("ecoffey")
ecoffey described the changes:
1) Small tweaks to the loader to bring it up to speed with new mono
versions and API wrapper changes that grim had made. (was in original
patch, just forgot about it :-P)
2) .NET Plugins are now required to define an Id as part of their info.
3) Modified gaim_probe_plugin to check for existence of info->id and to
make sure it's not empty; Prints an error, stores an error in the plugin
and sets plugin->unloadable = TRUE.
| 11660 | 1 | /* |
| 2 | * Mono Plugin Loader | |
| 3 | * | |
| 4 | * -- Thanks to the perl plugin loader for all the great tips ;-) | |
| 5 | * | |
| 6 | * Eoin Coffey | |
| 7 | */ | |
| 8 | ||
| 9 | #ifdef HAVE_CONFIG_H | |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
10 | # include <config.h> |
| 11660 | 11 | #endif |
| 12 | ||
| 13 | #include "internal.h" | |
| 14 | #include "debug.h" | |
| 15 | #include "plugin.h" | |
| 16 | #include "version.h" | |
| 17 | #include "mono-helper.h" | |
| 18 | ||
| 19 | #define MONO_PLUGIN_ID "core-mono" | |
| 20 | ||
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
21 | /****************************************************************************** |
|
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
22 | * Loader Stuff |
|
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
23 | *****************************************************************************/ |
| 11660 | 24 | /* probes the given plugin to determine if its a plugin */ |
| 15884 | 25 | static gboolean probe_mono_plugin(PurplePlugin *plugin) |
| 11660 | 26 | { |
| 27 | MonoAssembly *assm; | |
| 28 | MonoMethod *m = NULL; | |
| 29 | MonoObject *plugin_info; | |
|
15938
1b037158411e
SF Patch #1686400 from Eoin Coffey ("ecoffey")
Richard Laager <rlaager@pidgin.im>
parents:
15884
diff
changeset
|
30 | gboolean found_load = FALSE, found_unload = FALSE, found_destroy = FALSE; |
| 11660 | 31 | gpointer iter = NULL; |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
32 | |
| 15884 | 33 | PurplePluginInfo *info; |
| 34 | PurpleMonoPlugin *mplug; | |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
35 | |
| 11660 | 36 | char *file = plugin->path; |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
37 | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
38 | assm = mono_domain_assembly_open(ml_get_domain(), file); |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
39 | |
| 11660 | 40 | if (!assm) { |
| 41 | return FALSE; | |
| 42 | } | |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
43 | |
| 15884 | 44 | purple_debug(PURPLE_DEBUG_INFO, "mono", "Probing plugin\n"); |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
45 | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
46 | if (ml_is_api_dll(mono_assembly_get_image(assm))) { |
| 15884 | 47 | purple_debug(PURPLE_DEBUG_INFO, "mono", "Found our PurpleAPI.dll\n"); |
| 11660 | 48 | return FALSE; |
| 49 | } | |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
50 | |
| 15884 | 51 | info = g_new0(PurplePluginInfo, 1); |
| 52 | mplug = g_new0(PurpleMonoPlugin, 1); | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
53 | |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
54 | mplug->signal_data = NULL; |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
55 | |
| 11660 | 56 | mplug->assm = assm; |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
57 | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
58 | mplug->klass = ml_find_plugin_class(mono_assembly_get_image(mplug->assm)); |
| 11660 | 59 | if (!mplug->klass) { |
| 15884 | 60 | purple_debug(PURPLE_DEBUG_ERROR, "mono", "no plugin class in \'%s\'\n", file); |
| 11660 | 61 | return FALSE; |
| 62 | } | |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
63 | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
64 | mplug->obj = mono_object_new(ml_get_domain(), mplug->klass); |
| 11660 | 65 | if (!mplug->obj) { |
| 15884 | 66 | purple_debug(PURPLE_DEBUG_ERROR, "mono", "obj not valid\n"); |
| 11660 | 67 | return FALSE; |
| 68 | } | |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
69 | |
| 11660 | 70 | mono_runtime_object_init(mplug->obj); |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
71 | |
| 11660 | 72 | while ((m = mono_class_get_methods(mplug->klass, &iter))) { |
|
15938
1b037158411e
SF Patch #1686400 from Eoin Coffey ("ecoffey")
Richard Laager <rlaager@pidgin.im>
parents:
15884
diff
changeset
|
73 | purple_debug_info("mono", "plugin method: %s\n", mono_method_get_name(m)); |
| 11660 | 74 | if (strcmp(mono_method_get_name(m), "Load") == 0) { |
| 75 | mplug->load = m; | |
| 76 | found_load = TRUE; | |
| 77 | } else if (strcmp(mono_method_get_name(m), "Unload") == 0) { | |
| 78 | mplug->unload = m; | |
| 79 | found_unload = TRUE; | |
| 80 | } else if (strcmp(mono_method_get_name(m), "Destroy") == 0) { | |
| 81 | mplug->destroy = m; | |
| 82 | found_destroy = TRUE; | |
| 83 | } | |
| 84 | } | |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
85 | |
|
15938
1b037158411e
SF Patch #1686400 from Eoin Coffey ("ecoffey")
Richard Laager <rlaager@pidgin.im>
parents:
15884
diff
changeset
|
86 | if (!(found_load && found_unload && found_destroy)) { |
| 15884 | 87 | purple_debug(PURPLE_DEBUG_ERROR, "mono", "did not find the required methods\n"); |
| 11660 | 88 | return FALSE; |
| 89 | } | |
|
15938
1b037158411e
SF Patch #1686400 from Eoin Coffey ("ecoffey")
Richard Laager <rlaager@pidgin.im>
parents:
15884
diff
changeset
|
90 | |
|
1b037158411e
SF Patch #1686400 from Eoin Coffey ("ecoffey")
Richard Laager <rlaager@pidgin.im>
parents:
15884
diff
changeset
|
91 | plugin_info = ml_get_info_prop(mplug->obj); |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
92 | |
| 11660 | 93 | /* now that the methods are filled out we can populate |
| 94 | the info struct with all the needed info */ | |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
95 | |
|
15938
1b037158411e
SF Patch #1686400 from Eoin Coffey ("ecoffey")
Richard Laager <rlaager@pidgin.im>
parents:
15884
diff
changeset
|
96 | info->id = ml_get_prop_string(plugin_info, "Id"); |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
97 | info->name = ml_get_prop_string(plugin_info, "Name"); |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
98 | info->version = ml_get_prop_string(plugin_info, "Version"); |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
99 | info->summary = ml_get_prop_string(plugin_info, "Summary"); |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
100 | info->description = ml_get_prop_string(plugin_info, "Description"); |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
101 | info->author = ml_get_prop_string(plugin_info, "Author"); |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
102 | info->homepage = ml_get_prop_string(plugin_info, "Homepage"); |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
103 | |
| 15884 | 104 | info->magic = PURPLE_PLUGIN_MAGIC; |
| 105 | info->major_version = PURPLE_MAJOR_VERSION; | |
| 106 | info->minor_version = PURPLE_MINOR_VERSION; | |
| 107 | info->type = PURPLE_PLUGIN_STANDARD; | |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
108 | |
| 11660 | 109 | /* this plugin depends on us; duh */ |
| 110 | info->dependencies = g_list_append(info->dependencies, MONO_PLUGIN_ID); | |
| 111 | mplug->plugin = plugin; | |
| 112 | ||
| 113 | plugin->info = info; | |
| 114 | info->extra_info = mplug; | |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
115 | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
116 | ml_add_plugin(mplug); |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
117 | |
| 15884 | 118 | return purple_plugin_register(plugin); |
| 11660 | 119 | } |
| 120 | ||
| 121 | /* Loads a Mono Plugin by calling 'load' in the class */ | |
| 15884 | 122 | static gboolean load_mono_plugin(PurplePlugin *plugin) |
| 11660 | 123 | { |
| 15884 | 124 | PurpleMonoPlugin *mplug; |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
125 | |
| 15884 | 126 | purple_debug(PURPLE_DEBUG_INFO, "mono", "Loading plugin\n"); |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
127 | |
| 15884 | 128 | mplug = (PurpleMonoPlugin*)plugin->info->extra_info; |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
129 | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
130 | ml_invoke(mplug->load, mplug->obj, NULL); |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
131 | |
| 11660 | 132 | return TRUE; |
| 133 | } | |
| 134 | ||
| 135 | /* Unloads a Mono Plugin by calling 'unload' in the class */ | |
| 15884 | 136 | static gboolean unload_mono_plugin(PurplePlugin *plugin) |
| 11660 | 137 | { |
| 15884 | 138 | PurpleMonoPlugin *mplug; |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
139 | |
| 15884 | 140 | purple_debug(PURPLE_DEBUG_INFO, "mono", "Unloading plugin\n"); |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
141 | |
| 15884 | 142 | mplug = (PurpleMonoPlugin*)plugin->info->extra_info; |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
143 | |
| 15884 | 144 | purple_signals_disconnect_by_handle((gpointer)mplug->klass); |
|
11996
858bd928831c
[gaim-migrate @ 14289]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11980
diff
changeset
|
145 | g_list_foreach(mplug->signal_data, (GFunc)g_free, NULL); |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
146 | g_list_free(mplug->signal_data); |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
147 | mplug->signal_data = NULL; |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
148 | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
149 | ml_invoke(mplug->unload, mplug->obj, NULL); |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
150 | |
| 11660 | 151 | return TRUE; |
| 152 | } | |
| 153 | ||
| 15884 | 154 | static void destroy_mono_plugin(PurplePlugin *plugin) |
| 11660 | 155 | { |
| 15884 | 156 | PurpleMonoPlugin *mplug; |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
157 | |
| 15884 | 158 | purple_debug(PURPLE_DEBUG_INFO, "mono", "Destroying plugin\n"); |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
159 | |
| 15884 | 160 | mplug = (PurpleMonoPlugin*)plugin->info->extra_info; |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
161 | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
162 | ml_invoke(mplug->destroy, mplug->obj, NULL); |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
163 | |
| 11660 | 164 | if (plugin->info) { |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
165 | g_free(plugin->info->name); |
|
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
166 | g_free(plugin->info->version); |
|
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
167 | g_free(plugin->info->summary); |
|
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
168 | g_free(plugin->info->description); |
|
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
169 | g_free(plugin->info->author); |
|
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
170 | g_free(plugin->info->homepage); |
| 11660 | 171 | } |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
172 | |
| 11660 | 173 | if (mplug) { |
| 174 | if (mplug->assm) { | |
| 175 | mono_assembly_close(mplug->assm); | |
| 176 | } | |
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
177 | |
| 11660 | 178 | g_free(mplug); |
| 179 | mplug = NULL; | |
| 180 | } | |
| 181 | } | |
| 182 | ||
|
11786
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
183 | /****************************************************************************** |
|
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
184 | * Plugin Stuff |
|
d0067c6e542a
[gaim-migrate @ 14077]
Gary Kramlich <grim@reaperworld.com>
parents:
11679
diff
changeset
|
185 | *****************************************************************************/ |
| 15884 | 186 | static void plugin_destroy(PurplePlugin *plugin) |
| 11660 | 187 | { |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
188 | ml_uninit(); |
| 11660 | 189 | } |
| 190 | ||
| 15884 | 191 | static PurplePluginLoaderInfo loader_info = |
| 11660 | 192 | { |
| 193 | NULL, | |
| 194 | probe_mono_plugin, | |
| 195 | load_mono_plugin, | |
| 196 | unload_mono_plugin, | |
| 197 | destroy_mono_plugin | |
| 198 | }; | |
| 199 | ||
| 15884 | 200 | static PurplePluginInfo info = |
| 11660 | 201 | { |
| 15884 | 202 | PURPLE_PLUGIN_MAGIC, |
| 203 | PURPLE_MAJOR_VERSION, | |
| 204 | PURPLE_MINOR_VERSION, | |
| 205 | PURPLE_PLUGIN_LOADER, | |
| 11660 | 206 | NULL, |
| 207 | 0, | |
| 208 | NULL, | |
| 15884 | 209 | PURPLE_PRIORITY_DEFAULT, |
| 11660 | 210 | MONO_PLUGIN_ID, |
| 211 | N_("Mono Plugin Loader"), | |
| 212 | VERSION, | |
| 213 | N_("Loads .NET plugins with Mono."), | |
| 214 | N_("Loads .NET plugins with Mono."), | |
| 215 | "Eoin Coffey <ecoffey@simla.colostate.edu>", | |
| 15884 | 216 | PURPLE_WEBSITE, |
| 11660 | 217 | NULL, |
| 218 | NULL, | |
| 219 | plugin_destroy, | |
| 220 | NULL, | |
| 221 | &loader_info, | |
| 222 | NULL, | |
| 223 | NULL | |
| 224 | }; | |
| 225 | ||
| 15884 | 226 | static void init_plugin(PurplePlugin *plugin) |
| 11660 | 227 | { |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
228 | ml_init(); |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
229 | |
| 11660 | 230 | loader_info.exts = g_list_append(loader_info.exts, "dll"); |
| 231 | } | |
| 232 | ||
| 15884 | 233 | PURPLE_INIT_PLUGIN(mono, init_plugin, info) |