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 */