comparison src/plugins.c @ 90:f5b305c0d974

[gaim-migrate @ 100] Added plugin code. I have yet to test it. :P All I know is, I can successfully load a plugin. I don't know what I can do with it yet, and I'm not even sure I can unload it yet. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Fri, 07 Apr 2000 17:43:29 +0000
parents 2846a03bda67
children f3c6cf79f651
comparison
equal deleted inserted replaced
89:a382929aeb4f 90:f5b305c0d974
21 * The Plug-in plug 21 * The Plug-in plug
22 * 22 *
23 * Plugin support is currently being maintained by Mike Saraf 23 * Plugin support is currently being maintained by Mike Saraf
24 * msaraf@dwc.edu 24 * msaraf@dwc.edu
25 * 25 *
26 * Well, I didn't see any work done on it for a while, so I'm going to try
27 * my hand at it. - Eric warmenhoven@yahoo.com
28 *
26 */ 29 */
30
31 #ifdef GAIM_PLUGINS
27 32
28 #include <string.h> 33 #include <string.h>
29 #include <sys/time.h> 34 #include <sys/time.h>
30 35
31 #include <sys/types.h> 36 #include <sys/types.h>
35 #include <stdio.h> 40 #include <stdio.h>
36 #include <stdlib.h> 41 #include <stdlib.h>
37 #include <gtk/gtk.h> 42 #include <gtk/gtk.h>
38 #include "gaim.h" 43 #include "gaim.h"
39 44
45 #include <dlfcn.h>
46
40 /* ------------------ Local Variables -------------------------*/ 47 /* ------------------ Local Variables -------------------------*/
41 48
42 static GtkWidget *plugins=NULL; 49 static GtkWidget *plugin_dialog = NULL;
50 static GList *plugins = NULL;
51
52 static GtkWidget *pluglist;
53 static GtkWidget *plugtext;
43 54
44 /* --------------- Function Declarations -------------------- */ 55 /* --------------- Function Declarations -------------------- */
45 56
46 static void destroy_plugins(); 57 void load_plugin (GtkWidget *, gpointer);
47 void do_plugins(GtkWidget *, void *); 58 void unload_plugin(GtkWidget *, gpointer);
59 void show_plugins (GtkWidget *, gpointer);
60
61 static void destroy_plugins (GtkWidget *, gpointer);
62 static void load_which_plugin(GtkWidget *, gpointer);
63 static void unload (GtkWidget *, gpointer);
64 static void list_clicked (GtkWidget *, struct gaim_plugin *);
65
48 /* ------------------ Code Below ---------------------------- */ 66 /* ------------------ Code Below ---------------------------- */
49 67
50 void show_plugins() 68 static void destroy_plugins(GtkWidget *w, gpointer data) {
69 if (plugin_dialog)
70 gtk_widget_destroy(plugin_dialog);
71 plugin_dialog = NULL;
72 }
73
74 void load_plugin(GtkWidget *w, gpointer data)
51 { 75 {
52 char *buf = g_malloc(BUF_LEN); 76 char *buf = g_malloc(BUF_LEN);
53 77
54 if (!plugins) 78 if (!plugin_dialog) {
55 { 79 plugin_dialog = gtk_file_selection_new("Gaim - Plugin List");
56 plugins = gtk_file_selection_new("Gaim - Plugin List"); 80
57 81 gtk_file_selection_hide_fileop_buttons(
58 gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(plugins)); 82 GTK_FILE_SELECTION(plugin_dialog));
59 83
60 if(getenv("PLUGIN_DIR") == NULL) 84 if(getenv("PLUGIN_DIR") == NULL) {
61 { 85 g_snprintf(buf, BUF_LEN - 1, "%s/%s", getenv("HOME"), PLUGIN_DIR);
62 g_snprintf(buf, BUF_LEN - 1, "%s/", getenv("HOME")); 86 } else {
63 } 87 g_snprintf(buf, BUF_LEN - 1, "%s/", getenv("PLUGIN_DIR"));
64 else 88 }
65 { 89
66 g_snprintf(buf, BUF_LEN - 1, "%s/", getenv("PLUGIN_DIR")); 90 gtk_file_selection_set_filename(GTK_FILE_SELECTION(plugin_dialog), buf);
67 } 91 gtk_signal_connect(GTK_OBJECT(plugin_dialog), "destroy",
68 92 GTK_SIGNAL_FUNC(destroy_plugins), plugin_dialog);
69 gtk_file_selection_set_filename(GTK_FILE_SELECTION(plugins), buf); 93
70 gtk_signal_connect(GTK_OBJECT(plugins), "destroy", 94 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(plugin_dialog)->ok_button),
71 GTK_SIGNAL_FUNC(destroy_plugins), plugins); 95 "clicked", GTK_SIGNAL_FUNC(load_which_plugin), NULL);
72
73 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(plugins)->ok_button),
74 "clicked", GTK_SIGNAL_FUNC(do_plugins), NULL);
75 96
76 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(plugins)->cancel_button), 97 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(plugin_dialog)->cancel_button),
77 "clicked", GTK_SIGNAL_FUNC(destroy_plugins),plugins ); 98 "clicked", GTK_SIGNAL_FUNC(destroy_plugins), NULL);
78 99
79 } 100 }
80 101
81 gtk_widget_show(plugins); 102 g_free(buf);
82 gdk_window_raise(plugins->window); 103 gtk_widget_show(plugin_dialog);
83 } 104 gdk_window_raise(plugin_dialog->window);
84 105 }
85 void do_plugins(GtkWidget *w, void *dummy) 106
86 { 107 void load_which_plugin(GtkWidget *w, gpointer data) {
87 } 108 struct gaim_plugin *plug;
88 109 void (*gaim_plugin_init)();
89 static void destroy_plugins() 110 char *(*cfunc)();
90 { 111 int (*nfunc)();
91 if (plugins) 112 char *error;
92 gtk_widget_destroy(plugins); 113
93 114 plug = g_malloc(sizeof *plug);
94 plugins = NULL; 115 plug->filename = gtk_file_selection_get_filename(
95 } 116 GTK_FILE_SELECTION(plugin_dialog));
117 /* do NOT OR with RTLD_GLOBAL, otherwise plugins may conflict
118 * (it's really just a way to work around other people's bad
119 * programming, by not using RTLD_GLOBAL :P ) */
120 plug->handle = dlopen(plug->filename, RTLD_LAZY);
121 if (!plug->handle) {
122 error = dlerror();
123 do_error_dialog(error, "Plugin Error");
124 g_free(plug);
125 return;
126 }
127
128 if (plugin_dialog)
129 gtk_widget_destroy(plugin_dialog);
130 plugin_dialog = NULL;
131
132 gaim_plugin_init = dlsym(plug->handle, "gaim_plugin_init");
133 if ((error = dlerror()) != NULL) {
134 do_error_dialog(error, "Plugin Error");
135 dlclose(plug->handle);
136 g_free(plug);
137 return;
138 }
139
140 plugins = g_list_append(plugins, plug);
141 (*gaim_plugin_init)();
142
143 cfunc = dlsym(plug->handle, "name");
144 if ((error = dlerror()) == NULL)
145 plug->name = (*cfunc)();
146 else
147 plug->name = NULL;
148
149 cfunc = dlsym(plug->handle, "description");
150 if ((error = dlerror()) == NULL)
151 plug->description = (*cfunc)();
152 else
153 plug->description = NULL;
154 }
155
156 void unload_plugin(GtkWidget *w, gpointer data) {
157 /* FIXME */
158 }
159
160 void show_plugins(GtkWidget *w, gpointer data) {
161 /* most of this code was shamelessly stolen from prefs.c */
162 GtkWidget *window;
163 GtkWidget *page;
164 GtkWidget *topbox;
165 GtkWidget *botbox;
166 GtkWidget *sw;
167 GtkWidget *label;
168 GtkWidget *list_item;
169 GtkWidget *sw2;
170 GtkWidget *add;
171 GtkWidget *remove;
172 GList *plugs = plugins;
173 struct gaim_plugin *p;
174 gchar buffer[1024];
175
176 window = gtk_window_new(GTK_WINDOW_DIALOG);
177 gtk_widget_realize(window);
178 aol_icon(window->window);
179 gtk_container_border_width(GTK_CONTAINER(window), 10);
180 gtk_window_set_title(GTK_WINDOW(window), "Gaim - Plugins");
181
182 page = gtk_vbox_new(FALSE, 0);
183 topbox = gtk_hbox_new(FALSE, 0);
184 botbox = gtk_hbox_new(FALSE, 0);
185
186 sw2 = gtk_scrolled_window_new(NULL, NULL);
187 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw2),
188 GTK_POLICY_AUTOMATIC,
189 GTK_POLICY_AUTOMATIC);
190
191 pluglist = gtk_list_new();
192 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw2), pluglist);
193 gtk_box_pack_start(GTK_BOX(topbox), sw2, TRUE, TRUE, 0);
194
195 sw = gtk_scrolled_window_new(NULL, NULL);
196 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
197 GTK_POLICY_AUTOMATIC,
198 GTK_POLICY_AUTOMATIC);
199
200 plugtext = gtk_text_new(NULL, NULL);
201 gtk_container_add(GTK_CONTAINER(sw), plugtext);
202 gtk_box_pack_start(GTK_BOX(topbox), sw, TRUE, TRUE, 0);
203 gtk_text_set_word_wrap(GTK_TEXT(plugtext), TRUE);
204 gtk_text_set_editable(GTK_TEXT(plugtext), FALSE);
205
206 add = gtk_button_new_with_label("Load Plugin");
207 gtk_signal_connect(GTK_OBJECT(add), "clicked",
208 GTK_SIGNAL_FUNC(load_plugin), NULL);
209 gtk_box_pack_start(GTK_BOX(botbox), add, TRUE, FALSE, 5);
210
211 remove = gtk_button_new_with_label("Unload Plugin");
212 gtk_signal_connect(GTK_OBJECT(remove), "clicked",
213 GTK_SIGNAL_FUNC(unload), pluglist);
214 gtk_box_pack_start(GTK_BOX(botbox), remove, TRUE, FALSE, 5);
215
216 gtk_box_pack_start(GTK_BOX(page), topbox, TRUE, TRUE, 0);
217 gtk_box_pack_start(GTK_BOX(page), botbox, FALSE, FALSE, 0);
218
219 if (plugs != NULL) {
220 p = (struct gaim_plugin *)plugs->data;
221 g_snprintf(buffer, sizeof(buffer), "%s", p->filename);
222 gtk_text_insert(GTK_TEXT(plugtext), NULL, NULL, NULL, buffer, -1);
223 }
224
225 while (plugs) {
226 p = (struct gaim_plugin *)plugs->data;
227 label = gtk_label_new(p->filename);
228 list_item = gtk_list_item_new();
229 gtk_container_add(GTK_CONTAINER(list_item), label);
230 gtk_signal_connect(GTK_OBJECT(list_item), "select",
231 GTK_SIGNAL_FUNC(list_clicked), p);
232 gtk_object_set_user_data(GTK_OBJECT(list_item), p);
233
234 gtk_widget_show(label);
235 gtk_container_add(GTK_CONTAINER(pluglist), list_item);
236 gtk_widget_show(list_item);
237
238 plugs = plugs->next;
239 }
240
241 gtk_widget_show(page);
242 gtk_widget_show(topbox);
243 gtk_widget_show(botbox);
244 gtk_widget_show(sw);
245 gtk_widget_show(sw2);
246 gtk_widget_show(pluglist);
247 gtk_widget_show(plugtext);
248 gtk_widget_show(add);
249 gtk_widget_show(remove);
250
251 gtk_container_add(GTK_CONTAINER(window), page);
252 gtk_widget_show(window);
253 }
254
255 void unload(GtkWidget *w, gpointer data) {
256 GList *i;
257 struct gaim_plugin *p;
258 void (*gaim_plugin_remove)();
259 char *error;
260
261 i = GTK_LIST(pluglist)->selection;
262
263 p = gtk_object_get_user_data(GTK_OBJECT(i->data));
264
265 g_list_remove(plugins, p);
266
267 gaim_plugin_remove = dlsym(p->handle, "gaim_plugin_remove");
268 if ((error = dlerror()) == NULL)
269 (*gaim_plugin_remove)();
270 dlclose(p->handle);
271 g_free(p);
272 }
273
274 void list_clicked(GtkWidget *w, struct gaim_plugin *p) {
275 gchar buffer[2048];
276 guint text_len;
277
278 text_len = gtk_text_get_length(GTK_TEXT(plugtext));
279 gtk_text_set_point(GTK_TEXT(plugtext), 0);
280 gtk_text_forward_delete(GTK_TEXT(plugtext), text_len);
281
282 g_snprintf(buffer, sizeof buffer, "%s\n%s", p->name, p->description);
283 gtk_text_insert(GTK_TEXT(plugtext), NULL, NULL, NULL, buffer, -1);
284 }
285
286 #endif /* GAIM_PLUGINS */