? burn-extension.loT
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/ChangeLog,v
retrieving revision 1.559
diff -u -p -r1.559 ChangeLog
--- ChangeLog	16 Jan 2006 19:59:53 -0000	1.559
+++ ChangeLog	17 Jan 2006 01:57:30 -0000
@@ -1,3 +1,25 @@
+2006-01-16  Ryan Lortie  <desrt@desrt.ca>
+
+	* nautilus-burn-drive.c (fill_write_speeds)
+	(nautilus_burn_drive_get_max_write_speeds, hal_parse_write_speeds)
+	(hal_drive_from_udi, add_linux_cd_recorder, add_linux_cd_drive)
+	(freebsd_scan, cdrecord_scan, nautilus_burn_drive_get_file_image)
+	(nautilus_burn_drive_finalize, nautilus_burn_drive_init):
+	3 new functions to deal with having a list of possible write
+	speeds.  Added support for reading support drive speed from HAL.
+	Added call to fill_write_speeds to other functions to fill in default
+	write speeds (maxspeed× downto 1×) and also in the case where HAL
+	does not have the write_speeds property.  Added initialisation and
+	memory free code to init/finalize functions respectively.
+
+	* nautilus-burn-drive.h: Added write_speeds member.  Added
+	nautilus_burn_drive_get_write_speeds() prototype.
+
+	* nautilus-cd-burner.c (refresh_dialog): Replace old code which
+	obtained maximum drive speed and listed all speeds up to it with
+	code that lists the supported drive speeds as reported by
+	nautilus_burn_drive_get_write_speeds().
+
 2006-01-16  William Jon McCann  <mccann@jhu.edu>
 
 	* configure.in: Post release version bump.
Index: nautilus-burn-drive.c
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/nautilus-burn-drive.c,v
retrieving revision 1.47
diff -u -p -r1.47 nautilus-burn-drive.c
--- nautilus-burn-drive.c	14 Jan 2006 13:51:28 -0000	1.47
+++ nautilus-burn-drive.c	17 Jan 2006 01:57:32 -0000
@@ -141,6 +141,22 @@ static GObjectClass *parent_class = NULL
 
 G_DEFINE_TYPE(NautilusBurnDrive, nautilus_burn_drive, G_TYPE_OBJECT);
 
+/* fill in the write speeds as max_speed downto 1 if we
+ * are using a detection method that doesn't report all
+ * of the drive speeds
+ */
+static void
+fill_write_speeds (NautilusBurnDrive *drive)
+{
+	int max_speed = drive->max_speed_write;
+	int i;
+
+	drive->write_speeds = g_new0 (int, max_speed + 1);
+
+	for (i = 0; i < max_speed; i++)
+		drive->write_speeds[i] = max_speed - i;
+}
+
 #ifdef __FreeBSD__
 
 #define get_ioctl_handle_fd(x) (((struct cam_device *)x)->fd)
@@ -444,6 +460,30 @@ nautilus_burn_drive_get_max_speed_read (
 }
 
 /**
+ * nautilus_burn_drive_get_max_write_speeds:
+ * @drive: #NautilusBurnDrive
+ *
+ * Get the list of supported write speeds
+ *
+ * Returns: The write speeds of the drive, in device units, as a
+ * zero-terminated array of integers.  The array is sorted in
+ * descending order and has no duplicate entries.
+ *
+ * Since: 2.14
+ **/
+const int *
+nautilus_burn_drive_get_write_speeds (NautilusBurnDrive *drive)
+{
+	const int *speeds;
+
+	g_return_val_if_fail (drive != NULL, NULL);
+
+	speeds = drive->write_speeds;
+
+	return speeds;
+}
+
+/**
  * nautilus_burn_drive_get_name_for_display:
  * @drive: #NautilusBurnDrive
  *
@@ -1621,6 +1661,41 @@ drive_hal_init (NautilusBurnDrive *drive
 	drive->priv->ctx = ctx;
 }
 
+static int *
+hal_parse_write_speeds (char **strlist)
+{
+	char *end;
+	int  *write_speeds;
+	int   fields = 1;
+	int   i;
+
+	if (strlist == NULL)
+		return NULL;
+
+	fields = libhal_string_array_length (strlist);
+
+	if (fields == 0)
+		return NULL;
+
+	write_speeds = g_new0 (int, fields + 1);
+
+	for (i = 0; i < fields; i++)
+	{
+		write_speeds[i] = strtol (strlist[i], &end, 10);
+
+		if (write_speeds[i] < 0 || write_speeds[i] > 65535 ||
+			*end != '\0')
+		{
+			g_free (write_speeds);
+			return NULL;
+		}
+
+		write_speeds[i] /= CD_ROM_SPEED;
+	}
+
+	return write_speeds;
+}
+
 #define LIBHAL_PROP_EXTRACT_BEGIN if (FALSE)
 #define LIBHAL_PROP_EXTRACT_END ;
 #define LIBHAL_PROP_EXTRACT_INT(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_INT32) _where_ = libhal_psi_get_int (&it)
@@ -1628,7 +1703,7 @@ drive_hal_init (NautilusBurnDrive *drive
 #define LIBHAL_PROP_EXTRACT_STRING(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_STRING) _where_ = (libhal_psi_get_string (&it) != NULL && strlen (libhal_psi_get_string (&it)) > 0) ? strdup (libhal_psi_get_string (&it)) : NULL
 #define LIBHAL_PROP_EXTRACT_BOOL(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_BOOLEAN) _where_ = libhal_psi_get_bool (&it)
 #define LIBHAL_PROP_EXTRACT_BOOL_BITFIELD(_property_, _where_, _field_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_BOOLEAN) _where_ |= libhal_psi_get_bool (&it) ? _field_ : 0
-#define LIBHAL_PROP_EXTRACT_STRLIST(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_STRLIST) _where_ = my_strvdup (libhal_psi_get_strlist (&it))
+#define LIBHAL_PROP_EXTRACT_STRLIST(_property_, _where_) else if (strcmp (key, _property_) == 0 && type == LIBHAL_PROPERTY_TYPE_STRLIST) _where_ = libhal_psi_get_strlist (&it)
 
 static NautilusBurnDrive *
 hal_drive_from_udi (LibHalContext *ctx,
@@ -1638,6 +1713,7 @@ hal_drive_from_udi (LibHalContext *ctx,
 	LibHalPropertySetIterator it;
 	DBusError                 error;
 	NautilusBurnDrive        *drive;
+	char                    **write_speeds = NULL;
 
 	LIBHAL_CHECK_LIBHALCONTEXT (ctx, FALSE);
 
@@ -1664,12 +1740,12 @@ hal_drive_from_udi (LibHalContext *ctx,
 
 		LIBHAL_PROP_EXTRACT_BEGIN;
 
-		LIBHAL_PROP_EXTRACT_STRING  ("block.device",              drive->device);
-		LIBHAL_PROP_EXTRACT_STRING  ("storage.model",             drive->display_name);
-
-		LIBHAL_PROP_EXTRACT_INT_DIV ("storage.cdrom.read_speed",  drive->max_speed_read,  CD_ROM_SPEED);
-		LIBHAL_PROP_EXTRACT_INT_DIV ("storage.cdrom.write_speed", drive->max_speed_write, CD_ROM_SPEED);
+		LIBHAL_PROP_EXTRACT_STRING  ("block.device",               drive->device);
+		LIBHAL_PROP_EXTRACT_STRING  ("storage.model",              drive->display_name);
 
+		LIBHAL_PROP_EXTRACT_INT_DIV ("storage.cdrom.read_speed",   drive->max_speed_read,  CD_ROM_SPEED);
+		LIBHAL_PROP_EXTRACT_INT_DIV ("storage.cdrom.write_speed",  drive->max_speed_write, CD_ROM_SPEED);
+		LIBHAL_PROP_EXTRACT_STRLIST ("storage.cdrom.write_speeds", write_speeds);
 
 		LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdr",        drive->type, NAUTILUS_BURN_DRIVE_TYPE_CD_RECORDER);
 		LIBHAL_PROP_EXTRACT_BOOL_BITFIELD ("storage.cdrom.cdrw",       drive->type, NAUTILUS_BURN_DRIVE_TYPE_CDRW_RECORDER);
@@ -1684,15 +1760,18 @@ hal_drive_from_udi (LibHalContext *ctx,
 
 		LIBHAL_PROP_EXTRACT_END;
 	}
-
-	libhal_free_property_set (pset);
-
 	drive->priv->udi = g_strdup (udi);
 	drive->cdrecord_id = g_strdup (drive->device);
+	drive->write_speeds = hal_parse_write_speeds (write_speeds);
+	/* we do not own write_speeds so do not free it. */
+	if (drive->write_speeds == NULL)
+		fill_write_speeds (drive);
 
 	if (! drive->display_name)
 		drive->display_name = g_strdup_printf ("Unnamed Drive (%s)", drive->device);
 
+	libhal_free_property_set (pset);
+
 	return drive;
 }
 
@@ -2063,6 +2142,7 @@ add_linux_cd_recorder (GList            
 		/* Have a wild guess, the drive should actually correct us */
 		drive->max_speed_write = drive_s->speed;
 	}
+	fill_write_speeds (drive);
 
 	drive->device = g_strdup_printf ("/dev/%s", drive_s->device);
 	drive->max_speed_read = drive_s->speed;
@@ -2102,6 +2182,7 @@ add_linux_cd_drive (GList             *d
 	drive->display_name = g_strdup (drive_s->display_name);
 	drive->device = g_strdup_printf ("/dev/%s", drive_s->device);
 	drive->max_speed_write = 0; /* Can't write */
+	fill_write_speeds (drive);
 	drive->max_speed_read = drive_s->speed;
 	if (drive_s->can_read_dvd) {
 		drive->type |= NAUTILUS_BURN_DRIVE_TYPE_DVD_DRIVE;
@@ -2400,6 +2481,7 @@ freebsd_scan (gboolean recorder_only)
 			if (drive->max_speed_write == -1) {
 			    	drive->max_speed_write = speed;
 			}
+			fill_write_speeds (drive);
 
 			if (drive->type & NAUTILUS_BURN_DRIVE_TYPE_DVD_DRIVE) {
 				add_dvd_plus (drive);
@@ -2503,6 +2585,7 @@ cdrecord_scan (gboolean recorder_only)
 			if (drive->max_speed_write == -1) {
 			    	drive->max_speed_write = DEFAULT_SPEED;
 			}
+			fill_write_speeds (drive);
 
 			if (drive->type & NAUTILUS_BURN_DRIVE_TYPE_DVD_DRIVE) {
 				add_dvd_plus (drive);
@@ -2537,6 +2620,7 @@ nautilus_burn_drive_get_file_image (void
 	drive->display_name = g_strdup (_("File image"));
 	drive->max_speed_read = 0;
 	drive->max_speed_write = 0;
+	fill_write_speeds (drive);
 	drive->type = NAUTILUS_BURN_DRIVE_TYPE_FILE;
 
 	return drive;
@@ -2764,6 +2848,7 @@ nautilus_burn_drive_finalize (GObject *o
 	g_free (drive->priv->monitor_udi);
 
 	g_free (drive->display_name);
+	g_free (drive->write_speeds);
 	g_free (drive->cdrecord_id);
 	g_free (drive->device);
 
@@ -2781,6 +2866,7 @@ nautilus_burn_drive_init (NautilusBurnDr
 	drive->display_name    = NULL;
 	drive->max_speed_write = 0;
 	drive->max_speed_read  = 0;
+	drive->write_speeds    = NULL;
 	drive->cdrecord_id     = NULL;
 	drive->device          = NULL;
 
Index: nautilus-burn-drive.h
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/nautilus-burn-drive.h,v
retrieving revision 1.16
diff -u -p -r1.16 nautilus-burn-drive.h
--- nautilus-burn-drive.h	14 Jan 2006 13:51:28 -0000	1.16
+++ nautilus-burn-drive.h	17 Jan 2006 01:57:32 -0000
@@ -89,6 +89,7 @@ struct NautilusBurnDrive {
 	char                    *display_name;
 	int                      max_speed_write;
 	int                      max_speed_read;
+	int                     *write_speeds;
 	char                    *cdrecord_id;
 
 	NautilusBurnDrivePrivate *priv;
@@ -135,7 +136,7 @@ gboolean              nautilus_burn_driv
 
 int                   nautilus_burn_drive_get_max_speed_write      (NautilusBurnDrive       *drive);
 int                   nautilus_burn_drive_get_max_speed_read       (NautilusBurnDrive       *drive);
-
+const int *           nautilus_burn_drive_get_write_speeds         (NautilusBurnDrive       *drive);
 
 /* Media type handling */
 
Index: nautilus-cd-burner.c
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/nautilus-cd-burner.c,v
retrieving revision 1.167
diff -u -p -r1.167 nautilus-cd-burner.c
--- nautilus-cd-burner.c	2 Dec 2005 21:56:10 -0000	1.167
+++ nautilus-cd-burner.c	17 Jan 2006 01:57:34 -0000
@@ -1665,11 +1665,13 @@ refresh_dialog (GladeXML *xml)
 	GtkWidget               *combobox;
 	GConfClient             *gc;
 	char                    *name;
-	int                      i, default_speed;
+	int                      i, default_speed, default_speed_index;
 	NautilusBurnDrive       *drive;
 	GtkTreeModel            *model;
         GtkTreeIter              iter;
 
+	default_speed_index = 0;
+
 	/* Find active recorder: */
 	drive = lookup_current_recorder (xml);
 
@@ -1689,11 +1691,14 @@ refresh_dialog (GladeXML *xml)
 			    -1);
 
 	if (drive) {
-		int max_speed_write = nautilus_burn_drive_get_max_speed_write (drive);
+		const int *write_speeds = nautilus_burn_drive_get_write_speeds (drive);
 
-		for (i = 1; i <= max_speed_write; i++) {
-			name = g_strdup_printf ("%d \303\227", i);
+		for (i = 0; write_speeds[i] > 0; i++)
+		{
+			if (write_speeds[i] == default_speed)
+				default_speed_index = i;
 
+			name = g_strdup_printf ("%d \303\227", write_speeds[i]);
 			gtk_list_store_append (GTK_LIST_STORE (model), &iter);
 			gtk_list_store_set (GTK_LIST_STORE (model), &iter,
 					    0, name,
@@ -1702,13 +1707,11 @@ refresh_dialog (GladeXML *xml)
 			g_free (name);
 		}
 
-		/* Disable speed if max speed < 1 */
-		gtk_widget_set_sensitive (combobox, max_speed_write > 0);
-
+		/* Disable speed if no items in list */
+		gtk_widget_set_sensitive (combobox, i > 0);
 	}
 
-	/* for now assume equivalence between index in comboxbox and speed */
-	gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), default_speed);
+	gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), default_speed_index);
 
 	if (drive)
 		nautilus_burn_drive_unref (drive);
