diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index 443c1fb..d3262d6 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2007.02.02.173345" +#define Cdrskin_timestamP "2007.02.03.205526" diff --git a/libburn/async.c b/libburn/async.c index 4238211..99cc065 100644 --- a/libburn/async.c +++ b/libburn/async.c @@ -331,6 +331,13 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc) struct write_opts o; int i, j, mode, mixed_mode = 0; + /* For the next lines any return indicates failure */ + opts->drive->cancel = 1; + + /* ts A70203 : people have been warned in API specs */ + if (opts->write_type == BURN_WRITE_NONE) + return; + /* ts A61006 */ /* a ssert(!SCAN_GOING()); */ /* a ssert(!find_worker(opts->drive)); */ @@ -371,6 +378,8 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc) return; } + opts->drive->cancel = 0; /* End of the return = failure area */ + o.drive = opts->drive; o.opts = opts; o.disc = disc; diff --git a/libburn/drive.c b/libburn/drive.c index 015c931..1b39e2a 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -1558,3 +1558,111 @@ int burn_drive_free_speedlist(struct burn_speed_descriptor **speed_list) return burn_speed_descriptor_destroy(speed_list, 1); } + +/* ts A70203 : API function */ +int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt, + struct burn_multi_caps **caps, int flag) +{ + enum burn_disc_status s; + struct burn_multi_caps *o; + int status, num_formats, ret, type, i; + off_t size; + unsigned dummy; + + *caps = NULL; + s = burn_disc_get_status(d); + if(s == BURN_DISC_UNGRABBED) + return -1; + *caps = o = (struct burn_multi_caps *) + malloc(sizeof(struct burn_multi_caps)); + if(*caps == NULL) + return -1; + /* Default says nothing is available */ + o->multi_session = o->multi_track = 0; + o-> start_adr = 0; + o->start_alignment = o->start_range_low = o->start_range_high = 0; + o->might_do_tao = o->might_do_sao = o->might_do_raw = 0; + o->advised_write_mode = BURN_WRITE_NONE; + o->selected_write_mode = wt; + + if (s != BURN_DISC_BLANK && s != BURN_DISC_APPENDABLE) { + return 0; + } else if (s == BURN_DISC_APPENDABLE && + (wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW)) { + return 0; + } else if (d->current_profile == 0x09 || d->current_profile == 0x0a) { + /* CD-R , CD-RW */ + if (d->block_types[BURN_WRITE_TAO]) { + o->multi_session = o->multi_track = 1; + o->might_do_tao = 2; + if (o->advised_write_mode == BURN_WRITE_NONE) + o->advised_write_mode = BURN_WRITE_TAO; + } + if (d->block_types[BURN_WRITE_SAO]) { + o->multi_session = o->multi_track = 1; + o->might_do_sao = 1; + if (o->advised_write_mode == BURN_WRITE_NONE) + o->advised_write_mode = BURN_WRITE_SAO; + } + if (d->block_types[BURN_WRITE_RAW]) { + o->might_do_raw = 1; + if (o->advised_write_mode == BURN_WRITE_NONE) + o->advised_write_mode = BURN_WRITE_RAW; + } + } else if (d->current_profile == 0x11 || d->current_profile == 0x14) { + /* DVD-R , sequential DVD-RW */ + if (d->current_has_feat21h) { + o->multi_session = o->multi_track = 1; + o->might_do_tao = 2; + o->advised_write_mode = BURN_WRITE_TAO; + } + } else if (d->current_profile == 0x12 || d->current_profile == 0x13 || + d->current_profile == 0x1a) { + /* DVD-RAM, overwriteable DVD-RW, DVD+RW */ + o->start_adr = 1; + ret = burn_disc_get_formats(d, &status, &size, &dummy, + &num_formats); + if (ret == 1) { + if (status == BURN_FORMAT_IS_FORMATTED) + o->start_range_high = size; + if (d->current_profile == 0x13) { + o->start_alignment = 32 * 1024; + for (i = 0; i < num_formats; i++) { + ret = burn_disc_get_format_descr(d, i, + &type, &size, &dummy); + if (ret <= 0) + continue; + if (type == 0x13) /* expandable */ + break; + } + if (i >= num_formats) /* not expandable */ + o->start_range_high -= 32 * 1024; + } else { + o->start_alignment = 2 * 1024; + if (d->best_format_size - 2048 > + o->start_range_high) + o->start_range_high = + d->best_format_size - 2048; + } + } + o->might_do_tao = 2; + o->advised_write_mode = BURN_WRITE_TAO; + } else /* unknown media */ + return 0; + + if (s == BURN_DISC_APPENDABLE) + o->might_do_sao = o->might_do_raw = 0; + return 1; +} + + +/* ts A70203 : API function */ +int burn_disc_free_multi_caps(struct burn_multi_caps **caps) +{ + if (*caps == NULL) + return 0; + free((char *) *caps); + *caps = NULL; + return 1; +} + diff --git a/libburn/libburn.h b/libburn/libburn.h index 68e93b0..2517f5a 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -126,7 +126,14 @@ enum burn_write_types all subcodes must be provided by lib or user only raw block types are supported */ - BURN_WRITE_RAW + BURN_WRITE_RAW, + + /** In replies this indicates that not any writing will work. + As parameter for inquiries it indicates that no particular write + mode shall is specified. + Do not use for setting a write mode for burning. It won't work. + */ + BURN_WRITE_NONE }; /** Data format to send to the drive */ @@ -1254,11 +1261,11 @@ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi); /* ts A61222 */ /** Sets a start address for writing to media and write modes which allow to - choose this address at all (DVD+RW, DVD-RAM, DVD-RW only for now). The - address is given in bytes. If it is not -1 then a write run will fail if - choice of start address is not supported or if the block alignment of the - address is not suitable for media and write mode. (Alignment to 32 kB - blocks is advised with DVD media.) + choose this address at all (DVD+RW, DVD-RAM, formatted DVD-RW only for + now). The address is given in bytes. If it is not -1 then a write run + will fail if choice of start address is not supported or if the block + alignment of the address is not suitable for media and write mode. + (Alignment to 32 kB blocks is advised with DVD media.) @param opts The write opts to change @param value The address in bytes (-1 = start at default address) */ @@ -1370,6 +1377,93 @@ int burn_drive_get_speedlist(struct burn_drive *d, int burn_drive_free_speedlist(struct burn_speed_descriptor **speed_list); +/* ts A70203 */ +/** The reply structure for burn_disc_get_multi_caps() */ +struct burn_multi_caps { + + /* Multi-session capability allows to keep the media appendable after + writing a session. It also guarantees that the drive will be able + to predict and use the appropriate Next Writeable Address to place + the next session on the media without overwriting the existing ones. + 1= media may be kept appendable by burn_write_opts_set_multi(o,1) + 0= media will not be apendable appendable + */ + int multi_session; + + /* Multi-track capability allows to write more than one track source + during a single session. The written tracks can later be found in + libburn's TOC model with their start addresses and sizes. + 1= multiple tracks per session are allowed + 0= only one track per session allowed + */ + int multi_track; + + /* Start-address capability allows to set a non-zero address with + burn_write_opts_set_start_byte(). Eventually this has to respect + .start_alignment and .start_range_low, .start_range_high in this + structure. + 1= non-zero start address is allowed + 0= only start address 0 is allowed (to depict the drive's own idea + about the appropriate write start) + */ + int start_adr; + + /** The alignment for start addresses. + ( start_address % start_alignment ) must be 0. + */ + off_t start_alignment; + + /** The lowest permissible start address. + */ + off_t start_range_low; + + /** The highest addressable start address. + */ + off_t start_range_high; + + /** Potential availability of write modes + 2= available, no size prediction necessary + 1= available, needs exact size prediction + 0= not available + With CD media (profiles 0x09 and 0x0a) check also the elements + *_block_types of the according write mode. + */ + int might_do_tao; + int might_do_sao; + int might_do_raw; + + /* Advised write mode. + */ + enum burn_write_types advised_write_mode; + + /* Write mode as given by parameter wt of burn_disc_get_multi_caps(). + */ + enum burn_write_types selected_write_mode; +}; + +/** Allocates a struct burn_multi_caps (see above) and fills it with values + which are appropriate for the drive and the loaded media. The drive + must be grabbed for this call. The returned structure has to be disposed + via burn_disc_free_multi_caps() when no longer needed. + @param d The drive to inquire + @param wt With BURN_WRITE_NONE the best capabilities of all write modes + get returned. If set to a write mode like BURN_WRITE_TAO the + capabilities with that particular mode are returned. + @param caps returns the info structure + @param flag Bitfield for control purposes (unused yet, submit 0) + @return < 0 : error , 0 : writing seems impossible , 1 : writing possible +*/ +int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt, + struct burn_multi_caps **caps, int flag); + +/** Removes from memory a multi session info structure which was returned by + burn_disc_get_multi_caps(). The pointer *caps gets set o NULL. + @param caps the info structure to dispose (note: pointer to pointer) + @return 0 : *caps was already NULL, 1 : memory object was disposed +*/ +int burn_disc_free_multi_caps(struct burn_multi_caps **caps); + + /** Gets a copy of the toc_entry structure associated with a track @param t Track to get the entry from @param entry Struct for the library to fill out diff --git a/libburn/mmc.c b/libburn/mmc.c index 150ffe5..e8e18d9 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -1709,6 +1709,8 @@ int mmc_read_format_capacities(struct burn_drive *d, int top_wanted) score = 100 * sign; } else if(type == 0x15) { /* DVD-RW Quick */ score = 50 * sign; + } else if(type == 0x26) { /* DVD+RW */ + score = 1 * sign; } else { continue; } diff --git a/test/telltoc.c b/test/telltoc.c index c7fdfe3..4f324bf 100644 --- a/test/telltoc.c +++ b/test/telltoc.c @@ -228,6 +228,7 @@ int telltoc_media(struct burn_drive *drive) double max_speed = 0.0, min_speed = 0.0, speed_conv; enum burn_disc_status s; char profile_name[80], speed_unit[40]; + struct burn_multi_caps *caps; printf("Media current: "); ret = burn_disc_get_profile(drive, &profile_no, profile_name); @@ -273,6 +274,44 @@ int telltoc_media(struct burn_drive *drive) } else printf("is not recognizable\n"); + ret = burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0); + if (ret > 0) { + printf("Write multi : "); + printf("%s multi-session , ", + caps->multi_session == 1 ? "allows" : "prohibits"); + if (caps->multi_track) + printf("allows multiple tracks\n"); + else + printf("enforces single track\n"); + printf("Write start : "); + if (caps->start_adr == 1) + printf( + "allows addresses [%.f , %.f]s , alignment=%.fs\n", + (double) caps->start_range_low / 2048 , + (double) caps->start_range_high / 2048 , + (double) caps->start_alignment / 2048 ); + else + printf("prohibits write start addressing\n"); + printf("Write modes : "); + if (caps->might_do_tao) + printf("TAO%s", + caps->advised_write_mode == BURN_WRITE_TAO ? + " (advised)" : ""); + if (caps->might_do_sao) + printf("%sSAO%s", + caps->might_do_tao ? " , " : "", + caps->advised_write_mode == BURN_WRITE_SAO ? + " (advised)" : ""); + if (caps->might_do_raw) + printf("%sRAW%s", + caps->might_do_tao | caps->might_do_sao ? + " , " : "", + caps->advised_write_mode == BURN_WRITE_RAW ? + " (advised)" : ""); + printf("\n"); + burn_disc_free_multi_caps(&caps); + } + ret= burn_drive_get_write_speed(drive); max_speed = ((double ) ret) / speed_conv; ret= burn_drive_get_min_write_speed(drive);