diff 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
line wrap: on
line diff
--- a/src/prpl.c	Wed Jan 08 07:28:54 2003 +0000
+++ b/src/prpl.c	Wed Jan 08 08:18:49 2003 +0000
@@ -134,12 +134,35 @@
 	gtk_widget_destroy(b);
 }
 
+static GSList *do_ask_dialogs = NULL;
+
 struct doaskstruct {
+	GtkWidget *dialog;
+	GModule *handle;
 	void (*yesfunc)(gpointer);
 	void (*nofunc)(gpointer);
 	gpointer data;
 };
 
+void do_ask_cancel_by_handle(GModule *handle)
+{
+	GSList *d = do_ask_dialogs;
+
+	debug_printf("%d dialogs to search\n", g_slist_length(d));
+
+	while (d) {
+		GSList *cur = d;
+		struct doaskstruct *doask = d->data;
+
+		d = d->next;
+
+		if (doask->handle == handle) {
+			debug_printf("removing dialog, %d remain\n", g_slist_length(d));
+			gtk_dialog_response(GTK_DIALOG(doask->dialog), GTK_RESPONSE_NONE);
+		}
+	}
+}
+
 static void do_ask_callback(GtkDialog *d, gint resp, struct doaskstruct *doask)
 {
 	switch (resp) 
@@ -148,12 +171,12 @@
 			if (doask->yesfunc)
 				doask->yesfunc(doask->data);
 			break;
-		case GTK_RESPONSE_NO:
-		case GTK_RESPONSE_DELETE_EVENT:
+		default:
 			if (doask->nofunc)
 				doask->nofunc(doask->data);
 			break;
 		}
+	do_ask_dialogs = g_slist_remove(do_ask_dialogs, doask);
 	g_free(doask);
 	gtk_widget_destroy(GTK_WIDGET(d));
 }
@@ -163,7 +186,7 @@
                                    if (!strcmp(r,notext))  \
                                            notext = l;     
 
-void do_ask_dialog(const char *prim, const char *sec, void *data, char *yestext, void *doit, char *notext, void *dont, int modal)
+void do_ask_dialog(const char *prim, const char *sec, void *data, char *yestext, void *doit, char *notext, void *dont, GModule *handle, gboolean modal)
 {
 	GtkWidget *window;
 	GtkWidget *hbox;
@@ -173,10 +196,6 @@
 	GtkWidget *img = gtk_image_new_from_file(filename);
 	struct doaskstruct *doask = g_new0(struct doaskstruct, 1);
 
-	doask->yesfunc = doit;
-	doask->nofunc  = dont;
-	doask->data    = data;
-
 	g_free(filename);
 	gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
 
@@ -200,7 +219,7 @@
 
 	gtk_dialog_set_default_response (GTK_DIALOG(window), GTK_RESPONSE_YES);
 	g_signal_connect(G_OBJECT(window), "response", G_CALLBACK(do_ask_callback), doask);
-	
+
 	gtk_container_set_border_width (GTK_CONTAINER(window), 6);
 	gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
 	gtk_dialog_set_has_separator(GTK_DIALOG(window), FALSE);
@@ -217,7 +236,14 @@
 	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-	
+
+	doask->dialog  = window;
+	doask->handle  = handle;
+	doask->yesfunc = doit;
+	doask->nofunc  = dont;
+	doask->data    = data;
+	do_ask_dialogs = g_slist_append(do_ask_dialogs, doask);
+
 	gtk_widget_show_all(window);
 }
 
@@ -641,7 +667,7 @@
 	if (find_buddy(gc, ga->who))
 		do_error_dialog(buf, NULL, GAIM_INFO);
 	else
-		do_ask_dialog(buf, NULL, ga, _("Add"), do_add, _("Cancel"), dont_add, FALSE);
+		do_ask_dialog(buf, NULL, ga, _("Add"), do_add, _("Cancel"), dont_add, NULL, FALSE);
 }
 
 static GtkWidget *regdlg = NULL;
@@ -785,6 +811,7 @@
 		debug_printf("Protocol %s now in use by %d connections.\n", p->name, prpl_accounts[p->protocol]);
 		if(prpl_accounts[p->protocol] == 0) { /* No longer needed */
 			debug_printf("Throwing out %s protocol plugin\n", p->name);
+			do_ask_cancel_by_handle(p->plug->handle);
 			g_timeout_add(0, delayed_unload, p->plug->handle);
 			p->plug->handle = NULL;
 		}