? .Makefile.am.swp
? test
? test.c
? tmp.patch
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/ChangeLog,v
retrieving revision 1.256
diff -u -u -r1.256 ChangeLog
--- ChangeLog	23 Jul 2004 13:12:06 -0000	1.256
+++ ChangeLog	23 Jul 2004 16:48:45 -0000
@@ -1,3 +1,14 @@
+2004-07-23  Fernando Herrera  <fherrera@onirica.com>
+
+	* dvd_plus_rw_utils.cpp: MMC functions to get read/write speed
+	and blank disc size 
+	* cd-drive.c: (get_cd_properties):
+	(get_device_max_read_speed), (get_device_max_write_speed),
+	(add_linux_cd_recorder), (freebsd_scan), (cdrecord_scan):
+	Use MMC functions to get speeds.
+	(cd_drive_get_media_size_from_path), (cd_drive_get_media_size),
+	* cd-drive.h: New functions to get media size.
+
 2004-07-23  Bastien Nocera  <hadess@hadess.net>
 
 	* cd-drive.c: (cdrecord_scan): should be /dev/pgX not /dev/X for
Index: cd-drive.c
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/cd-drive.c,v
retrieving revision 1.38
diff -u -u -r1.38 cd-drive.c
--- cd-drive.c	23 Jul 2004 13:12:06 -0000	1.38
+++ cd-drive.c	23 Jul 2004 16:48:48 -0000
@@ -84,6 +84,7 @@
 
 /* Utility functions, be careful to have a match with what's use in the
  * different bits of code */
+#if !defined (__linux__)
 static char *
 cdrecord_get_stdout_for_id (char *id)
 {
@@ -117,9 +118,8 @@
 	return NULL;
 }
 
-#if !defined (__linux__)
 static void
-get_cd_properties (char *id, int *max_rd_speed, int *max_wr_speed,
+get_cd_properties (char *device, char *id, int *max_rd_speed, int *max_wr_speed,
 	CDDriveType *type)
 {
 	char *stdout_data, *rd_speed, *wr_speed, *drive_cap;
@@ -128,54 +128,13 @@
 	*max_wr_speed = -1;
 	*type = 0;
 
+	*max_rd_speed = get_device_max_read_speed (device);
+	*max_wr_speed = get_device_max_write_speed (device);
+
 	stdout_data = cdrecord_get_stdout_for_id (id);
 	if (stdout_data == NULL) {
 		return;
 	}
-
-	wr_speed = strstr (stdout_data, "Maximum write speed:");
-	if (wr_speed != NULL) {
-		char *tok;
-		wr_speed += strlen ("Maximum write speed:");
-		for (tok = strtok (wr_speed, " (),\t\n");
-				tok && strcmp (tok, "CD");
-				tok = strtok (NULL, " (),\t\n")) {}
-		tok = strtok (NULL, " (),\t\n"); /* Get the CD speed. */
-		*max_wr_speed = atol (tok);
-	} else {
-		wr_speed = strstr (stdout_data, "Maximum write speed in kB/s:");
-		if (wr_speed != NULL) {
-			char *tok;
-			wr_speed += strlen ("Maximum write speed in kB/s:");
-			for (tok = strtok (wr_speed, " (),\t\n");
-					tok && strcmp (tok, "CD");
-					tok = strtok (NULL, " (),\t\n")) {}
-			tok = strtok (NULL, " (),\t\n"); /* Get the CD speed. */
-			*max_wr_speed = atol (tok);
-		}
-	}
-
-	rd_speed = strstr (stdout_data, "Maximum read  speed:");
-	if (rd_speed != NULL) {
-		char *tok;
-		rd_speed += strlen ("Maximum read  speed:");
-		for (tok = strtok (rd_speed, " (),\t\n"); 
-				tok && strcmp (tok, "CD"); 
-				tok = strtok (NULL, " (),\t\n")) {}
-		tok = strtok (NULL, " (),\t\n"); /* Get the CD speed. */
-		*max_rd_speed = atol (tok);
-	} else {
-		rd_speed = strstr (stdout_data, "Maximum read  speed in kB/s:");
-		if (rd_speed != NULL) {
-			char *tok;
-			rd_speed += strlen ("Maximum read  speed in kB/s:");
-			for (tok = strtok (rd_speed, " (),\t\n");
-					tok && strcmp (tok, "CD");
-					tok = strtok (NULL, " (),\t\n")) {}
-			tok = strtok (NULL, " (),\t\n"); /* Get the CD speed. */
-			*max_rd_speed = atol (tok);
-		}
-	}
 	drive_cap = strstr (stdout_data, "Does write DVD-RAM media");
 	if (drive_cap != NULL) {
 		*type |= CDDRIVE_TYPE_DVD_RAM_RECORDER;
@@ -232,6 +191,9 @@
 /* For dvd_plus_rw_utils.cpp */
 int get_dvd_r_rw_profile (const char *name);
 int get_mmc_profile (int fd);
+int get_disc_size (int fd);
+int get_read_write_speed (int fd, int *read_speed, int *write_speed);
+
 
 static void
 add_dvd_plus (CDDrive *cdrom)
@@ -347,6 +309,34 @@
 	return cd_drive_get_media_type_from_path (cdrom->device);
 }
 
+int
+cd_drive_get_media_size_from_path (const char *device)
+{
+	int fd;
+	int secs = 0;
+
+	g_return_val_if_fail (device != NULL, CD_MEDIA_SIZE_UNKNOWN);
+
+	fd = open (device, O_RDONLY|O_EXCL|O_NONBLOCK);
+	if (fd < 0) {
+		return CD_MEDIA_SIZE_UNKNOWN;
+	}
+
+        secs = get_disc_size (fd);
+
+	close (fd);
+
+	return secs;
+}
+
+int
+cd_drive_get_media_size (CDDrive *cdrom)
+{
+	g_return_val_if_fail (cdrom != NULL, CD_MEDIA_SIZE_UNKNOWN);
+
+	return cd_drive_get_media_size_from_path (cdrom->device);
+}
+
 #ifdef USE_HAL
 
 #define GET_BOOL_PROP(x) (hal_device_property_exists (ctx, device_names[i], x) && hal_device_get_property_bool (ctx, device_names[i], x))
@@ -668,31 +658,43 @@
 }
 
 static int
-get_device_max_speed (char *id)
+get_device_max_read_speed (char *device)
 {
+	int fd;
 	int max_speed;
-	char *stdout_data, *speed;
+	int read_speed, write_speed;
 
 	max_speed = -1;
 
-	stdout_data = cdrecord_get_stdout_for_id (id);
-	if (stdout_data == NULL) {
-		return max_speed;
+	fd = open (device, O_RDONLY|O_EXCL|O_NONBLOCK);
+	if (fd < 0) {
+		return -1;
 	}
 
-	speed = strstr (stdout_data, "Maximum write speed in kB/s:");
-	if (speed != NULL) {
-		speed += strlen ("Maximum write speed in kB/s:");
-		max_speed = (int)floor (atol (speed) / 176.0 + 0.5);
-	} else {
-		speed = strstr (stdout_data, "Maximum write speed:");
-		if (speed != NULL) {
-			speed += strlen ("Maximum write speed:");
-			max_speed = (int)floor (atol (speed) / 176.0 + 0.5);
-		}
+	get_read_write_speed (fd, &read_speed, &write_speed);
+	close (fd);
+	max_speed = (int)floor  (read_speed) / CD_ROM_SPEED;
+
+	return max_speed;
+}
+
+static int
+get_device_max_write_speed (char *device)
+{
+	int fd;
+	int max_speed;
+	int read_speed, write_speed;
+
+	max_speed = -1;
+
+	fd = open (device, O_RDONLY|O_EXCL|O_NONBLOCK);
+	if (fd < 0) {
+		return -1;
 	}
 
-	g_free (stdout_data);
+	get_read_write_speed (fd, &read_speed, &write_speed);
+	close (fd);
+	max_speed = (int)floor  (write_speed) / CD_ROM_SPEED;
 
 	return max_speed;
 }
@@ -792,8 +794,8 @@
 	}
 
 	if (recorder_only) {
-		cdrom->max_speed_write = get_device_max_speed
-			(cdrom->cdrecord_id);
+		cdrom->max_speed_write = get_device_max_write_speed
+			(cdrom->device);
 		if (cdrom->max_speed_write == -1) {
 			cdrom->max_speed_write = cdrom_s->speed;
 		}
@@ -1120,7 +1122,7 @@
 		/* Attempt to get more specific information from
 		 * this drive by using cdrecord.
 		 */
-		get_cd_properties (cdrom->cdrecord_id,
+		get_cd_properties (cdrom->device, cdrom->cdrecord_id,
 			&(cdrom->max_speed_read),
 			&(cdrom->max_speed_write),
 			&(cdrom->type));
@@ -1224,7 +1226,7 @@
 		/* FIXME we don't have any way to guess the real device
 		 * from the info we get from CDRecord */
 		cdrom->device = g_strdup_printf ("/dev/pg%d", index);
-		get_cd_properties (cdrom->cdrecord_id,
+		get_cd_properties (cdrom->device, cdrom->cdrecord_id,
 			&(cdrom->max_speed_read),
 			&(cdrom->max_speed_write),
 			&(cdrom->type));
Index: cd-drive.h
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/cd-drive.h,v
retrieving revision 1.10
diff -u -u -r1.10 cd-drive.h
--- cd-drive.h	21 Jul 2004 22:37:07 -0000	1.10
+++ cd-drive.h	23 Jul 2004 16:48:48 -0000
@@ -43,6 +43,8 @@
 	CD_MEDIA_TYPE_DVD_PLUS_RW,
 } CDMediaType;
 
+#define CD_MEDIA_SIZE_UNKNOWN -1
+
 typedef enum {
 	CDDRIVE_TYPE_FILE                   = 1 << 0,
 	CDDRIVE_TYPE_CD_RECORDER            = 1 << 1,
@@ -68,11 +70,15 @@
 	CDDrivePriv *priv;
 } CDDrive;
 
+#define SECS_TO_MEGS(x) (int) (1 + x * 7 / 48)
+
 /* Returns a list of CDDrive structs */
 GList *scan_for_cdroms (gboolean recorder_only, gboolean add_image);
 void cd_drive_free (CDDrive *drive);
 CDMediaType cd_drive_get_media_type (CDDrive *drive);
 CDMediaType cd_drive_get_media_type_from_path (const char *device_path);
+int cd_drive_get_media_size (CDDrive *drive);
+int cd_drive_get_media_size_from_path (const char *device_path);
 CDDrive *cd_drive_get_file_image (void);
 
 #endif
Index: dvd_plus_rw_utils.cpp
===================================================================
RCS file: /cvs/gnome/nautilus-cd-burner/dvd_plus_rw_utils.cpp,v
retrieving revision 1.7
diff -u -u -r1.7 dvd_plus_rw_utils.cpp
--- dvd_plus_rw_utils.cpp	8 Jul 2004 07:53:38 -0000	1.7
+++ dvd_plus_rw_utils.cpp	23 Jul 2004 16:48:49 -0000
@@ -151,6 +151,134 @@
 }
 
 extern "C"
+int get_disc_size (int fd)
+{
+  Scsi_Command cmd(fd);
+  int retval = -1;
+  unsigned char toc[4], *atip;
+  int len;
+
+  /* For valgrind */
+  memset (&toc, 1, sizeof (toc));
+
+  cmd[0]=0x43; /* READ_TOC */
+  cmd[2]=4 & 0x0F;  /* FMT_ATIP */
+  cmd[6]=0;
+  cmd[8]=4;
+  cmd[9]=0;
+
+  if (cmd.transport(READ,toc,4))
+  {    
+	  goto bail;
+  }
+
+  len=2+(toc[0] << 8 | toc[1]);
+  atip=new unsigned char[len];
+  cmd[0]=0x43; /* READ_TOC */
+  cmd[2]=4 & 0x0F;  /* FMT_ATIP */
+  cmd[6]=0;
+  cmd[7]=len >> 8;
+  cmd[8]=len;        /* Real length */
+  cmd[9]=0;
+  if (cmd.transport(READ,atip,len))
+  {
+    goto bail;
+  }
+
+  return atip[12]*60+atip[13];
+
+bail:
+
+  return retval;
+
+}
+
+extern "C"
+int get_read_write_speed (int fd, int *read_speed, int *write_speed)
+{
+  Scsi_Command cmd(fd);
+  int retval = -1;
+  unsigned char header[12], *page2A, *p;
+  unsigned int len, bdlen, hlen;
+
+  *read_speed = 0;
+  *write_speed = 0;
+
+  /* For valgrind */
+  memset (&header, 1, sizeof (header));
+
+  cmd[0]=0x5A; /* MODE SENSE */
+  cmd[1]=0x08;  /* Disable Block Descriptors */
+  cmd[2]=0x2A;  /* Capabilities and Mechanical Status */
+  cmd[8]=12;
+  cmd[9]=0;
+
+  if (cmd.transport(READ,header,12))
+  {    
+    goto bail;
+  }
+  len=(header[0] << 8 | header[1]) + 2;
+  bdlen=header[6] << 8 | header[7];
+
+  if (bdlen)
+  {
+    if (len < (8 + bdlen + 30))
+    {
+      goto bail;
+    }
+  } else if (len < (8 + 2 + (unsigned int) header[9]))
+  {
+    /* SANYO does this. */
+    len = 8 + 2 + header[9];
+  }
+
+  page2A=new unsigned char[len];
+  cmd[0]=0x5A; /* MODE SENSE */
+  cmd[1]=0x08;  /* Disable Block Descriptors */
+  cmd[2]=0x2A;  /* Capabilities and Mechanical Status */
+  cmd[7]=len >> 8;
+  cmd[8]=len;        /* Real length */
+  cmd[9]=0;
+  if (cmd.transport(READ,page2A,len))
+  {
+      goto bail;
+  }
+  if (len < ((unsigned int) page2A[0] << 8 | page2A[1]))
+  {
+    page2A[0] = len >> 8;
+    page2A[1] = len;
+  }
+  len = (page2A[0] << 8 | page2A[1]) + 2;
+  hlen = 8 + (page2A[6] << 8 | page2A[7]);
+  p = page2A + hlen;
+
+  /* Values guessed from the cd_mode_page_2A struct
+  * in cdrecord's libscg/scg/scsireg.h */
+  if (len < (hlen + 30) || p[1] < (30 - 2))
+  {
+    /* no MMC-3 "Current Write Speed" present,
+     * try to use the MMC-2 one */
+    if (len < (hlen + 20) || p[1] < (20 - 2))
+      *write_speed = 0;
+    else
+      *write_speed = p[18] << 8 | p[19];
+  } else {
+    *write_speed = p[28] << 8 | p[29];
+  }
+
+  *read_speed = p[8] << 8 | p[9];
+
+  return 0;
+
+bail:
+
+  return -1;
+
+}
+
+
+
+extern "C"
 int get_mmc_profile (int fd)
 {
   Scsi_Command cmd(fd);
