| 74 #endif |
74 #endif |
| 75 |
75 |
| 76 /************************************************************************** |
76 /************************************************************************** |
| 77 * Plugin API |
77 * Plugin API |
| 78 **************************************************************************/ |
78 **************************************************************************/ |
| |
79 #ifdef PURPLE_PLUGINS |
| |
80 static gboolean |
| |
81 plugin_loading_cb(GObject *manager, PurplePlugin *plugin, GError **error, |
| |
82 gpointer data) |
| |
83 { |
| |
84 PurplePluginInfo *info; |
| |
85 PurplePluginInfoPrivate *priv; |
| |
86 |
| |
87 g_return_val_if_fail(PURPLE_IS_PLUGIN(plugin), FALSE); |
| |
88 |
| |
89 info = purple_plugin_get_info(plugin); |
| |
90 if (!info) |
| |
91 return TRUE; /* a GPlugin internal plugin */ |
| |
92 |
| |
93 priv = PURPLE_PLUGIN_INFO_GET_PRIVATE(info); |
| |
94 |
| |
95 if (priv->error) { |
| |
96 purple_debug_error("plugins", "Failed to load plugin %s: %s", |
| |
97 purple_plugin_get_filename(plugin), priv->error); |
| |
98 |
| |
99 g_set_error(error, PURPLE_PLUGINS_DOMAIN, 0, |
| |
100 "Plugin is not loadable: %s", priv->error); |
| |
101 |
| |
102 return FALSE; |
| |
103 } |
| |
104 |
| |
105 return TRUE; |
| |
106 } |
| |
107 |
| |
108 static void |
| |
109 plugin_loaded_cb(GObject *manager, PurplePlugin *plugin) |
| |
110 { |
| |
111 PurplePluginInfo *info; |
| |
112 |
| |
113 g_return_if_fail(PURPLE_IS_PLUGIN(plugin)); |
| |
114 |
| |
115 info = purple_plugin_get_info(plugin); |
| |
116 if (!info) |
| |
117 return; /* a GPlugin internal plugin */ |
| |
118 |
| |
119 loaded_plugins = g_list_append(loaded_plugins, plugin); |
| |
120 |
| |
121 purple_debug_info("plugins", "Loaded plugin %s\n", |
| |
122 purple_plugin_get_filename(plugin)); |
| |
123 |
| |
124 purple_signal_emit(purple_plugins_get_handle(), "plugin-load", plugin); |
| |
125 } |
| |
126 |
| |
127 static gboolean |
| |
128 plugin_unloading_cb(GObject *manager, PurplePlugin *plugin, GError **error, |
| |
129 gpointer data) |
| |
130 { |
| |
131 PurplePluginInfo *info; |
| |
132 |
| |
133 g_return_val_if_fail(PURPLE_IS_PLUGIN(plugin), FALSE); |
| |
134 |
| |
135 info = purple_plugin_get_info(plugin); |
| |
136 if (info) { |
| |
137 purple_debug_info("plugins", "Unloading plugin %s\n", |
| |
138 purple_plugin_get_filename(plugin)); |
| |
139 } |
| |
140 |
| |
141 return TRUE; |
| |
142 } |
| |
143 |
| |
144 static void |
| |
145 plugin_unloaded_cb(GObject *manager, PurplePlugin *plugin) |
| |
146 { |
| |
147 PurplePluginInfo *info; |
| |
148 PurplePluginInfoPrivate *priv; |
| |
149 |
| |
150 g_return_if_fail(PURPLE_IS_PLUGIN(plugin)); |
| |
151 |
| |
152 info = purple_plugin_get_info(plugin); |
| |
153 if (!info) |
| |
154 return; /* a GPlugin internal plugin */ |
| |
155 |
| |
156 priv = PURPLE_PLUGIN_INFO_GET_PRIVATE(info); |
| |
157 |
| |
158 /* cancel any pending dialogs the plugin has */ |
| |
159 purple_request_close_with_handle(plugin); |
| |
160 purple_notify_close_with_handle(plugin); |
| |
161 |
| |
162 purple_signals_disconnect_by_handle(plugin); |
| |
163 purple_signals_unregister_by_instance(plugin); |
| |
164 |
| |
165 priv->unloaded = TRUE; |
| |
166 |
| |
167 loaded_plugins = g_list_remove(loaded_plugins, plugin); |
| |
168 plugins_to_disable = g_list_remove(plugins_to_disable, plugin); |
| |
169 |
| |
170 purple_signal_emit(purple_plugins_get_handle(), "plugin-unload", plugin); |
| |
171 |
| |
172 purple_prefs_disconnect_by_handle(plugin); |
| |
173 } |
| |
174 #endif /* PURPLE_PLUGINS */ |
| |
175 |
| 79 gboolean |
176 gboolean |
| 80 purple_plugin_load(PurplePlugin *plugin, GError **error) |
177 purple_plugin_load(PurplePlugin *plugin, GError **error) |
| 81 { |
178 { |
| 82 #ifdef PURPLE_PLUGINS |
179 #ifdef PURPLE_PLUGINS |
| 83 GError *err = NULL; |
180 GError *err = NULL; |
| 84 PurplePluginInfoPrivate *priv; |
|
| 85 |
181 |
| 86 g_return_val_if_fail(plugin != NULL, FALSE); |
182 g_return_val_if_fail(plugin != NULL, FALSE); |
| 87 |
183 |
| 88 if (purple_plugin_is_loaded(plugin)) |
184 if (purple_plugin_is_loaded(plugin)) |
| 89 return TRUE; |
185 return TRUE; |
| 90 |
|
| 91 priv = PURPLE_PLUGIN_INFO_GET_PRIVATE(purple_plugin_get_info(plugin)); |
|
| 92 |
|
| 93 if (priv->error) { |
|
| 94 purple_debug_error("plugins", "Failed to load plugin %s: %s", |
|
| 95 purple_plugin_get_filename(plugin), priv->error); |
|
| 96 |
|
| 97 g_set_error(error, PURPLE_PLUGINS_DOMAIN, 0, |
|
| 98 "Plugin is not loadable: %s", priv->error); |
|
| 99 |
|
| 100 return FALSE; |
|
| 101 } |
|
| 102 |
186 |
| 103 if (!gplugin_plugin_manager_load_plugin(plugin, &err)) { |
187 if (!gplugin_plugin_manager_load_plugin(plugin, &err)) { |
| 104 purple_debug_error("plugins", "Failed to load plugin %s: %s", |
188 purple_debug_error("plugins", "Failed to load plugin %s: %s", |
| 105 purple_plugin_get_filename(plugin), |
189 purple_plugin_get_filename(plugin), |
| 106 (err ? err->message : "Unknown reason")); |
190 (err ? err->message : "Unknown reason")); |
| 130 gboolean |
207 gboolean |
| 131 purple_plugin_unload(PurplePlugin *plugin, GError **error) |
208 purple_plugin_unload(PurplePlugin *plugin, GError **error) |
| 132 { |
209 { |
| 133 #ifdef PURPLE_PLUGINS |
210 #ifdef PURPLE_PLUGINS |
| 134 GError *err = NULL; |
211 GError *err = NULL; |
| 135 PurplePluginInfoPrivate *priv; |
|
| 136 |
212 |
| 137 g_return_val_if_fail(plugin != NULL, FALSE); |
213 g_return_val_if_fail(plugin != NULL, FALSE); |
| 138 |
214 |
| 139 if (!purple_plugin_is_loaded(plugin)) |
215 if (!purple_plugin_is_loaded(plugin)) |
| 140 return TRUE; |
216 return TRUE; |
| 141 |
|
| 142 priv = PURPLE_PLUGIN_INFO_GET_PRIVATE(purple_plugin_get_info(plugin)); |
|
| 143 |
|
| 144 g_return_val_if_fail(priv != NULL, FALSE); |
|
| 145 |
|
| 146 purple_debug_info("plugins", "Unloading plugin %s\n", |
|
| 147 purple_plugin_get_filename(plugin)); |
|
| 148 |
217 |
| 149 if (!gplugin_plugin_manager_unload_plugin(plugin, &err)) { |
218 if (!gplugin_plugin_manager_unload_plugin(plugin, &err)) { |
| 150 purple_debug_error("plugins", "Failed to unload plugin %s: %s", |
219 purple_debug_error("plugins", "Failed to unload plugin %s: %s", |
| 151 purple_plugin_get_filename(plugin), |
220 purple_plugin_get_filename(plugin), |
| 152 (err ? err->message : "Unknown reason")); |
221 (err ? err->message : "Unknown reason")); |
| 155 *error = g_error_copy(err); |
224 *error = g_error_copy(err); |
| 156 g_error_free(err); |
225 g_error_free(err); |
| 157 |
226 |
| 158 return FALSE; |
227 return FALSE; |
| 159 } |
228 } |
| 160 |
|
| 161 /* cancel any pending dialogs the plugin has */ |
|
| 162 purple_request_close_with_handle(plugin); |
|
| 163 purple_notify_close_with_handle(plugin); |
|
| 164 |
|
| 165 purple_signals_disconnect_by_handle(plugin); |
|
| 166 purple_signals_unregister_by_instance(plugin); |
|
| 167 |
|
| 168 priv->unloaded = TRUE; |
|
| 169 |
|
| 170 loaded_plugins = g_list_remove(loaded_plugins, plugin); |
|
| 171 plugins_to_disable = g_list_remove(plugins_to_disable, plugin); |
|
| 172 |
|
| 173 purple_signal_emit(purple_plugins_get_handle(), "plugin-unload", plugin); |
|
| 174 |
|
| 175 purple_prefs_disconnect_by_handle(plugin); |
|
| 176 |
229 |
| 177 return TRUE; |
230 return TRUE; |
| 178 |
231 |
| 179 #else |
232 #else |
| 180 g_set_error(error, PURPLE_PLUGINS_DOMAIN, 0, "Plugin support is disabled."); |
233 g_set_error(error, PURPLE_PLUGINS_DOMAIN, 0, "Plugin support is disabled."); |
| 980 void |
1033 void |
| 981 purple_plugins_init(void) |
1034 purple_plugins_init(void) |
| 982 { |
1035 { |
| 983 void *handle = purple_plugins_get_handle(); |
1036 void *handle = purple_plugins_get_handle(); |
| 984 |
1037 |
| |
1038 /* TODO These should be removed, as GPlugin provides these signals as |
| |
1039 * GObject signals already. */ |
| 985 purple_signal_register(handle, "plugin-load", |
1040 purple_signal_register(handle, "plugin-load", |
| 986 purple_marshal_VOID__POINTER, |
1041 purple_marshal_VOID__POINTER, |
| 987 G_TYPE_NONE, 1, PURPLE_TYPE_PLUGIN); |
1042 G_TYPE_NONE, 1, PURPLE_TYPE_PLUGIN); |
| 988 purple_signal_register(handle, "plugin-unload", |
1043 purple_signal_register(handle, "plugin-unload", |
| 989 purple_marshal_VOID__POINTER, |
1044 purple_marshal_VOID__POINTER, |
| 990 G_TYPE_NONE, 1, PURPLE_TYPE_PLUGIN); |
1045 G_TYPE_NONE, 1, PURPLE_TYPE_PLUGIN); |
| 991 |
1046 |
| 992 #ifdef PURPLE_PLUGINS |
1047 #ifdef PURPLE_PLUGINS |
| 993 gplugin_init(); |
1048 gplugin_init(); |
| 994 purple_plugins_add_search_path(LIBDIR); |
1049 purple_plugins_add_search_path(LIBDIR); |
| |
1050 |
| |
1051 g_signal_connect(gplugin_plugin_manager_get_instance(), "loading-plugin", |
| |
1052 G_CALLBACK(plugin_loading_cb), NULL); |
| |
1053 g_signal_connect(gplugin_plugin_manager_get_instance(), "loaded-plugin", |
| |
1054 G_CALLBACK(plugin_loaded_cb), NULL); |
| |
1055 g_signal_connect(gplugin_plugin_manager_get_instance(), "unloading-plugin", |
| |
1056 G_CALLBACK(plugin_unloading_cb), NULL); |
| |
1057 g_signal_connect(gplugin_plugin_manager_get_instance(), "unloaded-plugin", |
| |
1058 G_CALLBACK(plugin_unloaded_cb), NULL); |
| |
1059 |
| 995 purple_plugins_refresh(); |
1060 purple_plugins_refresh(); |
| 996 #endif |
1061 #endif |
| 997 } |
1062 } |
| 998 |
1063 |
| 999 void |
1064 void |