Speeding up the startup time of the print dialog (2/2)



Here is the second patch, which makes libgnomeprint use the 
async ppd retrieval api introduced in the first patch. It changes
way in which the cups module populates the printer list to be
entirely done via the printer_added hooks of libgnomecups.

Matthias

Index: libgnomeprint/modules/cups/gnome-print-cups.c
===================================================================
RCS file: /cvs/gnome/libgnomeprint/libgnomeprint/modules/cups/gnome-print-cups.c,v
retrieving revision 1.35
diff -u -r1.35 gnome-print-cups.c
--- libgnomeprint/modules/cups/gnome-print-cups.c	21 Aug 2004 04:31:35 -0000	1.35
+++ libgnomeprint/modules/cups/gnome-print-cups.c	27 Aug 2004 20:12:58 -0000
@@ -43,6 +43,7 @@
 #include <libgnomecups/gnome-cups-printer.h>
 
 #include "libgnomeprint/gnome-print-i18n.h"
+static void get_ppd_cb (guint id, ppd_file_t *ppd, GError **error, gpointer user_data);
 
 /* Argument order: id, name */
 
@@ -144,7 +145,14 @@
 struct GnomePrintCupsNewPrinterCbData
 {
 	GPAList *list;
-	char *path;
+	char *module_path;
+};
+
+struct GnomePrintCupsLoadPrinterData
+{
+	GnomeCupsPrinter *printer;
+	GPAList *list;
+	char *module_path;
 };
 
 G_MODULE_EXPORT void gpa_module_load_data (GPAPrinter *printer);
@@ -412,44 +420,37 @@
 	return (GPAModel *)model;
 }
 
-static gboolean
-append_printer (GPAList *printers_list, GnomeCupsPrinter *cupsprinter,
-		gboolean is_default, const gchar *path)
-{
-	gboolean retval = FALSE;
-	const char *name = gnome_cups_printer_get_name (cupsprinter);
-	GPANode *printer  = gpa_printer_new_stub (name, name, path);
-
-	if (printer != NULL && gpa_node_verify (printer)) {
-		gpa_list_prepend (printers_list, printer);
-		if (is_default) {
-			gpa_list_set_default (printers_list, printer);
-			gpa_module_load_data (GPA_PRINTER (printer));
-		}
-		retval = TRUE;
-		g_signal_connect (cupsprinter, "gone",
-				  G_CALLBACK (printer_gone_cb),
-				  printers_list);
-	}
-
-	if (retval == FALSE) {
-		g_warning ("The CUPS printer %s could not be created\n", name);
-		my_gpa_node_unref (printer);
-	}
-
-	return retval;
+static void
+ free_ppd_retrieval_data (gpointer p)
+  {
+ 	struct GnomePrintCupsLoadPrinterData *data = p;
+ 	g_object_unref (data->printer);
+ 	g_free (data->module_path);
+ 	g_free (data);
+ }
+  
+ static void
+ start_printer_ppd_retrieval (GnomeCupsPrinter *printer,
+ 			     GPAList *printers_list,
+ 			     const char *module_path)
+ {
+ 	struct GnomePrintCupsLoadPrinterData *loaddata;
+ 	loaddata = g_new0 (struct GnomePrintCupsLoadPrinterData, 1);
+ 	loaddata->printer = g_object_ref (printer);
+ 	loaddata->list = printers_list;
+ 	loaddata->module_path = g_strdup (module_path);
+ 	gnome_cups_printer_get_ppd_async (printer,
+ 					  get_ppd_cb,
+ 					  loaddata,
+ 					  free_ppd_retrieval_data);
 }
 
 static 	GModule *handle = NULL;
 
 static void
 gnome_print_cups_printer_list_append (gpointer printers_list, 
-				      const gchar *path)
+				      const gchar *module_path)
 {
-	/* const gchar *def = cupsGetDefault(); 
-	   not reliable, dests[i].is_default used instead */
-        GList *printers = NULL;
-	GList *link;
 	struct GnomePrintCupsNewPrinterCbData *data;
 
 	g_return_if_fail (printers_list != NULL);
@@ -457,34 +458,17 @@
 
 	/* make ourselves resident */
 	if (!handle) 
-		handle = g_module_open (path, G_MODULE_BIND_LAZY);
+		handle = g_module_open (module_path, G_MODULE_BIND_LAZY);
 
-	gnome_cups_init (NULL);
 	data = g_new0 (struct GnomePrintCupsNewPrinterCbData, 1);
 	data->list = printers_list;
-	data->path = g_strdup (path);
+	data->module_path = g_strdup (module_path);
+	/* install printer_added_cb *before* calling gnome_cups_init(),
+	 * since that gets the list of printers 
+	 */
 	gnome_cups_printer_new_printer_notify_add ((GnomeCupsPrinterAddedCallback) printer_added_cb, data);
-	
-	printers = gnome_cups_get_printers ();
-	
-	for (link = printers; link; link = link->next) {
-		const char *name;
-		GnomeCupsPrinter *printer;
-
-		name = link->data;
-		printer = gnome_cups_printer_get (name);
-
-		if (printer) {
-			append_printer (GPA_LIST (printers_list),
-					printer,
-					gnome_cups_printer_get_is_default (printer),					
-					path);
-			g_object_unref (G_OBJECT (printer));
-		}
-	}
+	gnome_cups_init (NULL);	
 
-	gnome_cups_printer_list_free (printers);
-	
 	return;
 }
 
@@ -580,6 +564,117 @@
 }
 
 static void
+get_ppd_cb (guint id, ppd_file_t *ppd, GError **error, gpointer user_data)
+{
+	struct GnomePrintCupsLoadPrinterData *data = user_data;
+	const char *name;
+	GnomeCupsPrinter *cupsprinter;
+	GPANode *printer  = NULL;
+	GPANode *settings = NULL;
+	gboolean success = FALSE;
+	GPAModel *model = NULL;
+	GPAList *printers_list;
+
+	cupsprinter = data->printer;
+	printers_list = data->list;
+	name = gnome_cups_printer_get_name (data->printer);
+
+	if (ppd) {
+		model = get_model (name, ppd);
+	} else {
+		g_message ("The ppd file for the CUPS printer %s "
+			   "could not be loaded.", name);
+		model = get_model_no_ppd (name);
+	}
+
+	if (model == NULL) {
+		g_warning ("Couldn't create model for %s!\n", name);
+		goto out;
+	}
+
+	settings = gpa_settings_new (model, "Default", "SetIdFromCups");
+	if (settings == NULL) {
+		g_warning ("Couldn't create settings for %s!\n", name);
+		goto out;
+	}
+
+	printer = gpa_printer_new_stub (name, name, data->module_path);
+
+	if (printer != NULL && gpa_node_verify (printer)) {
+		gnome_print_cups_adjust_settings (GPA_SETTINGS (settings),
+						  cupsprinter);
+
+		success = gpa_printer_complete_stub (GPA_PRINTER (printer),
+						     model, 
+						     GPA_SETTINGS (settings));
+		
+		if (success) {
+			gpa_list_prepend (printers_list, printer);
+			if (gnome_cups_printer_get_is_default (cupsprinter)) {
+				gpa_list_set_default (printers_list, printer);
+			}
+			g_signal_connect (cupsprinter, "gone",
+					  G_CALLBACK (printer_gone_cb),
+					  printers_list);
+		}
+	} else {
+		g_warning ("The CUPS printer %s could not be created\n", name);
+		my_gpa_node_unref (printer);
+		goto out;
+	}
+
+	if (success) {
+		add_printer_location (cupsprinter, GPA_PRINTER (printer));
+		attributes_changed_cb (cupsprinter, GPA_PRINTER (printer));
+	}
+
+	/* Do we have to add any further instances */
+	/* FIXME - punt on instance bits for now */
+/* 	{ */
+/* 		char *id = g_strdup_printf ("SetIdFromCups-%s", printer->name); */
+/* 		settings = gpa_settings_new (model, printer->name, id); */
+/* 		g_free (id); */
+/* 		id = NULL; */
+/* 		if (settings != NULL) { */
+/* 			gnome_print_cups_adjust_settings (GPA_SETTINGS (settings), */
+/* 							  cupsprinter); */
+/* 			gpa_list_prepend (GPA_NODE (printer->settings), */
+/* 					  GPA_NODE (settings)); */
+/* 			GPA_SETTINGS (settings)->printer */
+/* 				= gpa_reference_new (GPA_NODE (printer), "Printer"); */
+/* 		} */
+/* 	} */
+
+ out:
+	if (success == FALSE) {
+		g_warning ("The data for the CUPS printer %s "
+			   "could not be loaded.", name);
+
+		if (model != NULL)
+			my_gpa_node_unref (GPA_NODE (model));
+		if (settings != NULL)
+			my_gpa_node_unref (settings);
+	}
+
+	if (ppd) {
+		ppdClose (ppd);
+	}
+
+/* 	gpa_utils_dump_tree (GPA_NODE (printer),5); */
+}
+
+static void
+printer_attributes_changed_cb (GnomeCupsPrinter *printer,
+			       gpointer d)
+{
+	struct GnomePrintCupsNewPrinterCbData *data = d;	
+		start_printer_ppd_retrieval (printer,
+					     data->list,
+					     data->module_path);
+		g_object_unref (printer);
+}
+
+static void
 printer_added_cb (const char *name, struct GnomePrintCupsNewPrinterCbData *data)
 {
 	GPANode *node;
@@ -591,13 +686,14 @@
 	}
 
 	printer = gnome_cups_printer_get (name);
-	if (printer != NULL) {
-		append_printer (data->list, printer, FALSE, data->path);
-		g_object_unref (printer);
+	if (!gnome_cups_printer_get_attributes_initialized (printer)) {
+		g_signal_connect (printer,
+				  "attributes-changed",
+				  G_CALLBACK (printer_attributes_changed_cb),
+				  data);
+	} else {
+		printer_attributes_changed_cb (printer, data);
 	}
-	else
-		g_warning ("Printer %s does not exist!", name);
-	
 }
 
 static void
@@ -655,79 +751,6 @@
 
 G_MODULE_EXPORT void gpa_module_load_data (GPAPrinter *printer)
 {
-	GPANode *settings = NULL;
-	GPAModel *model    = NULL;
-	const char *name   = printer->name;
-	ppd_file_t *ppd    = NULL;
-	gboolean success   = FALSE;
-	GnomeCupsPrinter *cupsprinter;
-	
-	if (printer->is_complete)
-		return;
-
-	cupsprinter = gnome_cups_printer_get (printer->name);
-
-	if (cupsprinter) {
-		ppd = gnome_cups_printer_get_ppd (cupsprinter);
-		if (ppd) {
-			model = get_model (name, ppd);
-		}
-	}
-	if (!ppd) {
-		g_warning ("The ppd file for the CUPS printer %s "
-			   "could not be loaded.", name);
-		model = get_model_no_ppd (name);
-	}
-	if (model == NULL)
-		goto gpa_module_load_data_exit;
-
-	settings = gpa_settings_new (model, "Default", "SetIdFromCups");
-	if (settings == NULL)
-		goto gpa_module_load_data_exit;
-
-	gnome_print_cups_adjust_settings (GPA_SETTINGS (settings), cupsprinter);
-
-	success = gpa_printer_complete_stub (printer, model, 
-					     GPA_SETTINGS (settings));
-
-	add_printer_location (cupsprinter, printer);
-	attributes_changed_cb (cupsprinter, printer);
-
-	/* Do we have to add any further instances */
-	/* FIXME - punt on instance bits for now */
-/* 	{ */
-/* 		char *id = g_strdup_printf ("SetIdFromCups-%s", name); */
-/* 		settings = gpa_settings_new (model, name, id); */
-/* 		g_free (id); */
-/* 		id = NULL; */
-/* 		if (settings != NULL) { */
-/* 			gnome_print_cups_adjust_settings (GPA_SETTINGS (settings), */
-/* 							  cupsprinter); */
-/* 			gpa_list_prepend (GPA_NODE (printer->settings), */
-/* 					  GPA_NODE (settings)); */
-/* 			GPA_SETTINGS (settings)->printer */
-/* 				= gpa_reference_new (GPA_NODE (printer), "Printer"); */
-/* 		} */
-/* 	} */
-
- gpa_module_load_data_exit:
-	g_object_unref (cupsprinter);
-	if (success == FALSE) {
-		g_warning ("The data for the CUPS printer %s "
-			   "could not be loaded.", name);
-
-		if (model != NULL)
-			my_gpa_node_unref (GPA_NODE (model));
-		if (settings != NULL)
-			my_gpa_node_unref (settings);
-	}
-
-	if (ppd) {
-		ppdClose (ppd);
-	}
-
-/* 	gpa_utils_dump_tree (GPA_NODE (printer),5); */
-	return;
 }
 
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]