Mercurial > pidgin
comparison src/prpl.c @ 4249:9c7fcb211886
[gaim-migrate @ 4499]
If anyone is curious, the commit before this fixed a bug which
didn't allow you to delete AIM or ICQ people from a deny list.
They'll show up when you sign back online, and will be deleteable
now.
This is a patch from the good Mr. McQueen.
"Twofold attack:
1) Make sure all the callback functions don't throw a mental if the gc
the dialog was asking about has disappeared. Make sure the functions
still free up the data structs as necessary in this case.
2) When setting up a ask dialog, plugins (including prpls) pass in their
handle. The ask dialog struct gets kept in a slist. When unloading a
plugin or prpl, Gaim checks the handle against the list, and sends a
cancel-type message for any outstanding dialogs.
Should avoid crashes from non-modal ask dialogs lying around."
Yeah, so that's a nice lil' improvement.
I also fixed a think where SSI "authorization denied" messages
would be gibberish. That was a bug from just a few hours ago.
Whoops.
Also, since this is like a grown up version of show and tell, I
thought this was funny:
* Robot101 fixes idiocy
<KingAnt> Does that mean I'm going to be nuetered?
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Wed, 08 Jan 2003 08:18:49 +0000 |
parents | cd84b0fd63fc |
children | 32fcf4cf5f80 |
comparison
equal
deleted
inserted
replaced
4248:ea8fb193f5a0 | 4249:9c7fcb211886 |
---|---|
132 static void des_win(GtkWidget *a, GtkWidget *b) | 132 static void des_win(GtkWidget *a, GtkWidget *b) |
133 { | 133 { |
134 gtk_widget_destroy(b); | 134 gtk_widget_destroy(b); |
135 } | 135 } |
136 | 136 |
137 static GSList *do_ask_dialogs = NULL; | |
138 | |
137 struct doaskstruct { | 139 struct doaskstruct { |
140 GtkWidget *dialog; | |
141 GModule *handle; | |
138 void (*yesfunc)(gpointer); | 142 void (*yesfunc)(gpointer); |
139 void (*nofunc)(gpointer); | 143 void (*nofunc)(gpointer); |
140 gpointer data; | 144 gpointer data; |
141 }; | 145 }; |
146 | |
147 void do_ask_cancel_by_handle(GModule *handle) | |
148 { | |
149 GSList *d = do_ask_dialogs; | |
150 | |
151 debug_printf("%d dialogs to search\n", g_slist_length(d)); | |
152 | |
153 while (d) { | |
154 GSList *cur = d; | |
155 struct doaskstruct *doask = d->data; | |
156 | |
157 d = d->next; | |
158 | |
159 if (doask->handle == handle) { | |
160 debug_printf("removing dialog, %d remain\n", g_slist_length(d)); | |
161 gtk_dialog_response(GTK_DIALOG(doask->dialog), GTK_RESPONSE_NONE); | |
162 } | |
163 } | |
164 } | |
142 | 165 |
143 static void do_ask_callback(GtkDialog *d, gint resp, struct doaskstruct *doask) | 166 static void do_ask_callback(GtkDialog *d, gint resp, struct doaskstruct *doask) |
144 { | 167 { |
145 switch (resp) | 168 switch (resp) |
146 { | 169 { |
147 case GTK_RESPONSE_YES: | 170 case GTK_RESPONSE_YES: |
148 if (doask->yesfunc) | 171 if (doask->yesfunc) |
149 doask->yesfunc(doask->data); | 172 doask->yesfunc(doask->data); |
150 break; | 173 break; |
151 case GTK_RESPONSE_NO: | 174 default: |
152 case GTK_RESPONSE_DELETE_EVENT: | |
153 if (doask->nofunc) | 175 if (doask->nofunc) |
154 doask->nofunc(doask->data); | 176 doask->nofunc(doask->data); |
155 break; | 177 break; |
156 } | 178 } |
179 do_ask_dialogs = g_slist_remove(do_ask_dialogs, doask); | |
157 g_free(doask); | 180 g_free(doask); |
158 gtk_widget_destroy(GTK_WIDGET(d)); | 181 gtk_widget_destroy(GTK_WIDGET(d)); |
159 } | 182 } |
160 | 183 |
161 #define STOCK_ITEMIZE(r, l) if (!strcmp(r,yestext)) \ | 184 #define STOCK_ITEMIZE(r, l) if (!strcmp(r,yestext)) \ |
162 yestext = l; \ | 185 yestext = l; \ |
163 if (!strcmp(r,notext)) \ | 186 if (!strcmp(r,notext)) \ |
164 notext = l; | 187 notext = l; |
165 | 188 |
166 void do_ask_dialog(const char *prim, const char *sec, void *data, char *yestext, void *doit, char *notext, void *dont, int modal) | 189 void do_ask_dialog(const char *prim, const char *sec, void *data, char *yestext, void *doit, char *notext, void *dont, GModule *handle, gboolean modal) |
167 { | 190 { |
168 GtkWidget *window; | 191 GtkWidget *window; |
169 GtkWidget *hbox; | 192 GtkWidget *hbox; |
170 GtkWidget *label; | 193 GtkWidget *label; |
171 char labeltext[1024 * 2]; | 194 char labeltext[1024 * 2]; |
172 char *filename = g_build_filename(DATADIR, "pixmaps", "gaim", "dialogs", "gaim_question.png", NULL); | 195 char *filename = g_build_filename(DATADIR, "pixmaps", "gaim", "dialogs", "gaim_question.png", NULL); |
173 GtkWidget *img = gtk_image_new_from_file(filename); | 196 GtkWidget *img = gtk_image_new_from_file(filename); |
174 struct doaskstruct *doask = g_new0(struct doaskstruct, 1); | 197 struct doaskstruct *doask = g_new0(struct doaskstruct, 1); |
175 | |
176 doask->yesfunc = doit; | |
177 doask->nofunc = dont; | |
178 doask->data = data; | |
179 | 198 |
180 g_free(filename); | 199 g_free(filename); |
181 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); | 200 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); |
182 | 201 |
183 /* This is ugly. GTK Stock items will take a button with a label "gtk-cancel" and turn it into a | 202 /* This is ugly. GTK Stock items will take a button with a label "gtk-cancel" and turn it into a |
198 gtk_window_set_modal(GTK_WINDOW(window), TRUE); | 217 gtk_window_set_modal(GTK_WINDOW(window), TRUE); |
199 } | 218 } |
200 | 219 |
201 gtk_dialog_set_default_response (GTK_DIALOG(window), GTK_RESPONSE_YES); | 220 gtk_dialog_set_default_response (GTK_DIALOG(window), GTK_RESPONSE_YES); |
202 g_signal_connect(G_OBJECT(window), "response", G_CALLBACK(do_ask_callback), doask); | 221 g_signal_connect(G_OBJECT(window), "response", G_CALLBACK(do_ask_callback), doask); |
203 | 222 |
204 gtk_container_set_border_width (GTK_CONTAINER(window), 6); | 223 gtk_container_set_border_width (GTK_CONTAINER(window), 6); |
205 gtk_window_set_resizable(GTK_WINDOW(window), FALSE); | 224 gtk_window_set_resizable(GTK_WINDOW(window), FALSE); |
206 gtk_dialog_set_has_separator(GTK_DIALOG(window), FALSE); | 225 gtk_dialog_set_has_separator(GTK_DIALOG(window), FALSE); |
207 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(window)->vbox), 12); | 226 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(window)->vbox), 12); |
208 gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(window)->vbox), 6); | 227 gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(window)->vbox), 6); |
215 label = gtk_label_new(NULL); | 234 label = gtk_label_new(NULL); |
216 gtk_label_set_markup(GTK_LABEL(label), labeltext); | 235 gtk_label_set_markup(GTK_LABEL(label), labeltext); |
217 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | 236 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); |
218 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | 237 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); |
219 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | 238 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); |
220 | 239 |
240 doask->dialog = window; | |
241 doask->handle = handle; | |
242 doask->yesfunc = doit; | |
243 doask->nofunc = dont; | |
244 doask->data = data; | |
245 do_ask_dialogs = g_slist_append(do_ask_dialogs, doask); | |
246 | |
221 gtk_widget_show_all(window); | 247 gtk_widget_show_all(window); |
222 } | 248 } |
223 | 249 |
224 static void des_prompt(GtkWidget *w, struct _prompt *p) | 250 static void des_prompt(GtkWidget *w, struct _prompt *p) |
225 { | 251 { |
639 msg ? msg : "", | 665 msg ? msg : "", |
640 find_buddy(gc, ga->who) ? "" : _("\n\nDo you wish to add him or her to your buddy list?")); | 666 find_buddy(gc, ga->who) ? "" : _("\n\nDo you wish to add him or her to your buddy list?")); |
641 if (find_buddy(gc, ga->who)) | 667 if (find_buddy(gc, ga->who)) |
642 do_error_dialog(buf, NULL, GAIM_INFO); | 668 do_error_dialog(buf, NULL, GAIM_INFO); |
643 else | 669 else |
644 do_ask_dialog(buf, NULL, ga, _("Add"), do_add, _("Cancel"), dont_add, FALSE); | 670 do_ask_dialog(buf, NULL, ga, _("Add"), do_add, _("Cancel"), dont_add, NULL, FALSE); |
645 } | 671 } |
646 | 672 |
647 static GtkWidget *regdlg = NULL; | 673 static GtkWidget *regdlg = NULL; |
648 static GtkWidget *reg_list = NULL; | 674 static GtkWidget *reg_list = NULL; |
649 static GtkWidget *reg_area = NULL; | 675 static GtkWidget *reg_area = NULL; |
783 if(p->plug) { /* This protocol is a plugin */ | 809 if(p->plug) { /* This protocol is a plugin */ |
784 prpl_accounts[p->protocol]--; | 810 prpl_accounts[p->protocol]--; |
785 debug_printf("Protocol %s now in use by %d connections.\n", p->name, prpl_accounts[p->protocol]); | 811 debug_printf("Protocol %s now in use by %d connections.\n", p->name, prpl_accounts[p->protocol]); |
786 if(prpl_accounts[p->protocol] == 0) { /* No longer needed */ | 812 if(prpl_accounts[p->protocol] == 0) { /* No longer needed */ |
787 debug_printf("Throwing out %s protocol plugin\n", p->name); | 813 debug_printf("Throwing out %s protocol plugin\n", p->name); |
814 do_ask_cancel_by_handle(p->plug->handle); | |
788 g_timeout_add(0, delayed_unload, p->plug->handle); | 815 g_timeout_add(0, delayed_unload, p->plug->handle); |
789 p->plug->handle = NULL; | 816 p->plug->handle = NULL; |
790 } | 817 } |
791 } | 818 } |
792 #endif /* GAIM_PLUGINS */ | 819 #endif /* GAIM_PLUGINS */ |