diff --git a/example/Makefile.am b/example/Makefile.am index 1e22759a..40902a26 100644 --- a/example/Makefile.am +++ b/example/Makefile.am @@ -1,4 +1,4 @@ -# $Id: Makefile.am,v 1.4 2004/02/01 17:12:33 rocky Exp $ +# $Id: Makefile.am,v 1.5 2004/07/08 01:27:57 rocky Exp $ # # Copyright (C) 2003, 2004 Rocky Bernstein # @@ -20,7 +20,8 @@ # Things to regression testing #################################################### # -noinst_PROGRAMS = sample1 sample2 sample3 sample4 sample5 sample6 sample7 +noinst_PROGRAMS = sample1 sample2 sample3 sample4 sample5 sample6 \ + sample7 sample8 INCLUDES = -I$(top_srcdir) $(LIBCDIO_CFLAGS) @@ -31,3 +32,4 @@ sample4_LDADD = $(LIBCDIO_LIBS) sample5_LDADD = $(LIBCDIO_LIBS) sample6_LDADD = $(LIBISO9660_LIBS) $(LIBCDIO_LIBS) sample7_LDADD = $(LIBISO9660_LIBS) $(LIBCDIO_LIBS) +sample8_LDADD = $(LIBCDIO_LIBS) diff --git a/include/cdio/Makefile.am b/include/cdio/Makefile.am index e1ef076d..19045de1 100644 --- a/include/cdio/Makefile.am +++ b/include/cdio/Makefile.am @@ -1,6 +1,6 @@ -# $Id: Makefile.am,v 1.9 2004/05/10 03:28:51 rocky Exp $ +# $Id: Makefile.am,v 1.10 2004/07/08 01:27:58 rocky Exp $ # -# Copyright (C) 2003 Rocky Bernstein +# Copyright (C) 2003, 2004 Rocky Bernstein # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -24,6 +24,7 @@ libcdioincludedir=$(includedir)/cdio libcdioinclude_HEADERS = \ cdio.h \ + cdtext.h \ cd_types.h \ iso9660.h \ logging.h \ diff --git a/include/cdio/cdtext.h b/include/cdio/cdtext.h new file mode 100644 index 00000000..8fd9d377 --- /dev/null +++ b/include/cdio/cdtext.h @@ -0,0 +1,87 @@ +/* + $Id: cdtext.h,v 1.1 2004/07/08 01:27:58 rocky Exp $ + + Copyright (C) 2004 Rocky Bernstein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/*! + * \file cdtext.h + * \brief Header CDTEXT information +*/ + + +#ifndef __CDIO_CDTEXT_H__ +#define __CDIO_CDTEXT_H__ + +#include + +#define CDIO_CDTEXT_MAX_PACK_DATA 255 +#define CDIO_CDTEXT_MAX_TEXT_DATA 12 + +#define CDIO_CDTEXT_TITLE 0x80 +#define CDIO_CDTEXT_PERFORMER 0x81 +#define CDIO_CDTEXT_SONGWRITER 0x82 +#define CDIO_CDTEXT_COMPOSER 0x83 +#define CDIO_CDTEXT_ARRANGER 0x84 +#define CDIO_CDTEXT_MESSAGE 0x85 +#define CDIO_CDTEXT_DISCID 0x86 +#define CDIO_CDTEXT_GENRE 0x87 + +PRAGMA_BEGIN_PACKED + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct CDText_data +{ + uint8_t type; + track_t i_track; + uint8_t seq; + uint8_t characterPosition:4; /* character position */ + uint8_t block:3; /* block number 0..7 */ + uint8_t bDBC:1; /* double byte character */ + char text[12]; + uint8_t crc[2]; +} GNUC_PACKED; + +PRAGMA_END_PACKED + +typedef struct CDText_data CDText_data_t; + +/** + * Query the CDTEXT information + * + * @param cd The CD object to extract CDTEXT data from + * + * @return An allocated structure containing CDTEXT information found. + * NULL is returned if there was a problem. + */ +CDText_data_t *cdio_cdtext_query(const CdIo *cd); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CDIO_ISO9660_H__ */ + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/cdio/scsi_mmc.h b/include/cdio/scsi_mmc.h index 5d894f83..60de66f3 100644 --- a/include/cdio/scsi_mmc.h +++ b/include/cdio/scsi_mmc.h @@ -1,5 +1,5 @@ /* - $Id: scsi_mmc.h,v 1.5 2004/06/27 22:00:08 rocky Exp $ + $Id: scsi_mmc.h,v 1.6 2004/07/08 01:27:59 rocky Exp $ Copyright (C) 2003, 2004 Rocky Bernstein @@ -36,17 +36,18 @@ /*! The generic packet command opcodes for CD/DVD Logical Units. */ -#define CDIO_MMC_MODE_SENSE 0x1a -#define CDIO_MMC_START_STOP 0x1b -#define CDIO_MMC_GPCMD_READ_10 0x28 -#define CDIO_MMC_GPCMD_READ_SUBCHANNEL 0x42 -#define CDIO_MMC_READ_TOC 0x43 -#define CDIO_MMC_MODE_SELECT 0x55 -#define CDIO_MMC_MODE_SELECT_6 0x15 -#define CDIO_MMC_MODE_SENSE_10 0x5a -#define CDIO_MMC_GPCMD_READ_12 0xa8 -#define CDIO_MMC_GPCMD_READ_CD 0xbe -#define CDIO_MMC_GPCMD_READ_MSF 0xb9 +#define CDIO_MMC_GPCMD_MODE_SENSE 0x1a +#define CDIO_MMC_GPCMD_START_STOP 0x1b +#define CDIO_MMC_GPCMD_READ_10 0x28 +#define CDIO_MMC_GPCMD_READ_SUBCHANNEL 0x42 +#define CDIO_MMC_GPCMD_READ_TOC 0x43 +#define CDIO_MMC_GPCMD_MODE_SELECT 0x55 +#define CDIO_MMC_GPCMD_MODE_SELECT_6 0x15 +#define CDIO_MMC_GPCMD_MODE_SENSE_10 0x5a +#define CDIO_MMC_GPCMD_READ_12 0xa8 +#define CDIO_MMC_GPCMD_READ_CD 0xbe +#define CDIO_MMC_GPCMD_READ_MSF 0xb9 +#define CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL 0x1e /*! Page codes for MODE SENSE and MODE SET. */ diff --git a/lib/FreeBSD/freebsd_cam.c b/lib/FreeBSD/freebsd_cam.c index 83d8b3ee..993228f4 100644 --- a/lib/FreeBSD/freebsd_cam.c +++ b/lib/FreeBSD/freebsd_cam.c @@ -1,5 +1,5 @@ /* - $Id: freebsd_cam.c,v 1.14 2004/06/27 22:00:09 rocky Exp $ + $Id: freebsd_cam.c,v 1.15 2004/07/08 01:28:00 rocky Exp $ Copyright (C) 2004 Rocky Bernstein @@ -26,7 +26,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: freebsd_cam.c,v 1.14 2004/06/27 22:00:09 rocky Exp $"; +static const char _rcsid[] = "$Id: freebsd_cam.c,v 1.15 2004/07/08 01:28:00 rocky Exp $"; #ifdef HAVE_FREEBSD_CDROM @@ -348,7 +348,8 @@ stat_size_freebsd_cam (_img_private_t *env) sizeof(env->ccb.csio.sense_data), 0, 30*1000); env->ccb.csio.cdb_len = 8+1; - CDIO_MMC_SET_COMMAND(env->ccb.csio.cdb_io.cdb_bytes, CDIO_MMC_READ_TOC); + CDIO_MMC_SET_COMMAND(env->ccb.csio.cdb_io.cdb_bytes, + CDIO_MMC_GPCMD_READ_TOC); env->ccb.csio.cdb_io.cdb_bytes[1] = 0; /* lba; msf: 0x2 */ CDIO_MMC_SET_START_TRACK(env->ccb.csio.cdb_io.cdb_bytes, CDIO_CDROM_LEADOUT_TRACK); @@ -393,7 +394,8 @@ eject_media_freebsd_cam (_img_private_t *env) 0, 30*1000); env->ccb.csio.cdb_len = 5+1; - CDIO_MMC_SET_COMMAND(env->ccb.csio.cdb_io.cdb_bytes, CDIO_MMC_START_STOP); + CDIO_MMC_SET_COMMAND(env->ccb.csio.cdb_io.cdb_bytes, + CDIO_MMC_GPCMD_START_STOP); env->ccb.csio.cdb_io.cdb_bytes[1] = 0x1; /* immediate */ env->ccb.csio.cdb_io.cdb_bytes[4] = 0x2; /* eject */ diff --git a/lib/MSWindows/aspi32.c b/lib/MSWindows/aspi32.c index 3bce3c09..998ca855 100644 --- a/lib/MSWindows/aspi32.c +++ b/lib/MSWindows/aspi32.c @@ -1,5 +1,5 @@ /* - $Id: aspi32.c,v 1.12 2004/06/28 00:24:00 rocky Exp $ + $Id: aspi32.c,v 1.13 2004/07/08 01:28:01 rocky Exp $ Copyright (C) 2004 Rocky Bernstein @@ -27,7 +27,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: aspi32.c,v 1.12 2004/06/28 00:24:00 rocky Exp $"; +static const char _rcsid[] = "$Id: aspi32.c,v 1.13 2004/07/08 01:28:01 rocky Exp $"; #include #include @@ -542,7 +542,7 @@ read_toc_aspi (_img_private_t *env) ssc.SRB_CDBLen = 10; /* Operation code */ - CDIO_MMC_SET_COMMAND(ssc.CDBByte, CDIO_MMC_READ_TOC); + CDIO_MMC_SET_COMMAND(ssc.CDBByte, CDIO_MMC_CPCMD_READ_TOC); /* Format */ ssc.CDBByte[ 2 ] = READ_TOC_FORMAT_TOC; @@ -707,7 +707,7 @@ get_drive_cap_aspi (const _img_private_t *env) ssc.SRB_CDBLen = 12; /* Operation code */ - CDIO_MMC_SET_COMMAND(ssc.CDBByte, CDIO_MMC_MODE_SENSE_10); + CDIO_MMC_SET_COMMAND(ssc.CDBByte, CDIO_MMC_GPCMD_MODE_SENSE_10); ssc.CDBByte[1] = 0x0; ssc.CDBByte[2] = CDIO_MMC_ALL_PAGES; ssc.CDBByte[7] = 0x01; diff --git a/lib/_cdio_linux.c b/lib/_cdio_linux.c index 47419692..ef1e78b7 100644 --- a/lib/_cdio_linux.c +++ b/lib/_cdio_linux.c @@ -1,5 +1,5 @@ /* - $Id: _cdio_linux.c,v 1.59 2004/06/27 16:36:38 rocky Exp $ + $Id: _cdio_linux.c,v 1.60 2004/07/08 01:27:59 rocky Exp $ Copyright (C) 2001 Herbert Valerio Riedel Copyright (C) 2002, 2003, 2004 Rocky Bernstein @@ -27,13 +27,14 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.59 2004/06/27 16:36:38 rocky Exp $"; +static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.60 2004/07/08 01:27:59 rocky Exp $"; #include #include #include #include +#include #include "cdio_assert.h" #include "cdio_private.h" @@ -67,6 +68,8 @@ static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.59 2004/06/27 16:36:38 rock #include #include +typedef struct cdrom_generic_command cgc_t; + #define TOTAL_TRACKS (env->tochdr.cdth_trk1) #define FIRST_TRACK_NUM (env->tochdr.cdth_trk0) @@ -260,7 +263,6 @@ static int _cdio_mmc_read_sectors (int fd, void *buf, lba_t lba, int sector_type, unsigned int nblocks) { - typedef struct cdrom_generic_command cgc_t; cgc_t cgc; memset (&cgc, 0, sizeof (cgc_t)); @@ -672,6 +674,114 @@ _cdio_read_toc (_img_private_t *env) return true; } +static CDText_data_t * +_cdtext_query( void *user_data ) +{ + +#ifdef CDTEXT_FIXED + _img_private_t *env = user_data; + CDText_data_t *pdata; + int i; + int j; + char buffer[5000]; + char buf[256]; + int idx; + track_t i_track; + cgc_t cgc; + int status; + + memset (&cgc, 0, sizeof (cgc)); + memset (&buffer, 0, sizeof (buffer)); + + cgc.cmd[0] = CDIO_MMC_GPCMD_READ_TOC; + cgc.cmd[1] = 0x02; /* MSF mode */ + cgc.cmd[2] = 0x05; /* CD text */ + CDIO_MMC_SET_READ_LENGTH( cgc.cmd, sizeof(buffer) ); + + status = ioctl( env->gen.fd, CDROM_SEND_PACKET, &cgc ); + + if( status != 0 ) { + cdio_warn ("CDTEXT reading failed: %s\n", strerror(errno)); + return NULL; + } + + memset (&buf, 0, sizeof (buffer)); + idx = 0; + + pdata = (CDText_data_t *) (&buffer[4]); + for( i=0; i < CDIO_CDTEXT_MAX_PACK_DATA; i++ ) + { + if( pdata->seq != i ) + break; + + if( (pdata->type >= 0x80) && (pdata->type <= 0x87) && (pdata->block == 0) ) + { + i_track = pdata->i_track; + + for( j=0; j < CDIO_CDTEXT_MAX_TEXT_DATA; j++ ) { + if( pdata->text[j] == 0x00 ) { + switch( pdata->type) { + case CDIO_CDTEXT_TITLE: + if( i_track == 0 ) + printf("Album Title: %s\n", buf); + else + printf("Title track %d: %s\n", i_track, buf); + i_track++; + idx = 0; + break; + + case CDIO_CDTEXT_PERFORMER: + if( i_track == 0 ) + printf("Album Performer %s\n", buf); + else + printf("Performer track %d: %s\n", i_track, buf); + i_track++; + idx = 0; + break; + case CDIO_CDTEXT_COMPOSER: + if( i_track == 0 ) + printf("Album Composer %s\n", buf); + else + printf("Composer track %d: %s\n", i_track, buf); + i_track++; + idx = 0; + break; + case CDIO_CDTEXT_ARRANGER: + if( i_track == 0 ) + printf("Album Arranger %s\n", buf); + else + printf("Arranger track %d: %s\n", i_track, buf); + i_track++; + idx = 0; + break; + case CDIO_CDTEXT_MESSAGE: + printf("Extended data: %s\n", buf); + i_track++; + idx = 0; + break; + case CDIO_CDTEXT_GENRE: + printf("Genre %s\n", buf); + i_track++; + idx = 0; + break; + case CDIO_CDTEXT_DISCID: + printf("Discid track%s\n", buf); + idx = 0; + break; + } + } + else { + buffer[idx++] = pdata->text[j]; + } + buffer[idx] = 0x00; + } + } + pdata++; + } +#endif + return NULL; /* FIXME */ +} + /* * Eject using SCSI commands. Return 1 if successful, 0 otherwise. */ @@ -685,9 +795,10 @@ _eject_media_mmc(int fd) char cmd[256]; } scsi_cmd; - scsi_cmd.inlen = 0; + CDIO_MMC_SET_COMMAND(scsi_cmd.cmd, CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL); + + scsi_cmd.inlen = 0; scsi_cmd.outlen = 0; - scsi_cmd.cmd[0] = ALLOW_MEDIUM_REMOVAL; scsi_cmd.cmd[1] = 0; scsi_cmd.cmd[2] = 0; scsi_cmd.cmd[3] = 0; @@ -695,11 +806,11 @@ _eject_media_mmc(int fd) scsi_cmd.cmd[5] = 0; status = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd); if (status != 0) - return 0; + return status; scsi_cmd.inlen = 0; scsi_cmd.outlen = 0; - CDIO_MMC_SET_COMMAND(scsi_cmd.cmd, CDIO_MMC_START_STOP); + CDIO_MMC_SET_COMMAND(scsi_cmd.cmd, CDIO_MMC_GPCMD_START_STOP); scsi_cmd.cmd[1] = 0; scsi_cmd.cmd[2] = 0; scsi_cmd.cmd[3] = 0; @@ -707,23 +818,24 @@ _eject_media_mmc(int fd) scsi_cmd.cmd[5] = 0; status = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd); if (status != 0) - return 0; + return status; scsi_cmd.inlen = 0; scsi_cmd.outlen = 0; - CDIO_MMC_SET_COMMAND(scsi_cmd.cmd, CDIO_MMC_START_STOP); + CDIO_MMC_SET_COMMAND(scsi_cmd.cmd, CDIO_MMC_GPCMD_START_STOP); scsi_cmd.cmd[1] = 0; scsi_cmd.cmd[2] = 0; scsi_cmd.cmd[3] = 0; - scsi_cmd.cmd[4] = 2; + scsi_cmd.cmd[4] = 2; /* eject */ scsi_cmd.cmd[5] = 0; status = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd); if (status != 0) - return 0; + return status; /* force kernel to reread partition table when new disc inserted */ status = ioctl(fd, BLKRRPART); - return (status == 0); + return (status); + } /*! @@ -1100,6 +1212,7 @@ cdio_open_am_linux (const char *psz_orig_source, const char *access_mode) char *psz_source; cdio_funcs _funcs = { + .cdtext_query = _cdtext_query, .eject_media = _eject_media_linux, .free = cdio_generic_free, .get_arg = _get_arg_linux, diff --git a/lib/cdio.c b/lib/cdio.c index 740a134f..7416dfce 100644 --- a/lib/cdio.c +++ b/lib/cdio.c @@ -1,5 +1,5 @@ /* - $Id: cdio.c,v 1.56 2004/06/19 19:15:15 rocky Exp $ + $Id: cdio.c,v 1.57 2004/07/08 01:28:00 rocky Exp $ Copyright (C) 2003, 2004 Rocky Bernstein Copyright (C) 2001 Herbert Valerio Riedel @@ -39,7 +39,7 @@ #include #include "cdio_private.h" -static const char _rcsid[] = "$Id: cdio.c,v 1.56 2004/06/19 19:15:15 rocky Exp $"; +static const char _rcsid[] = "$Id: cdio.c,v 1.57 2004/07/08 01:28:00 rocky Exp $"; const char *track_format2str[6] = @@ -212,6 +212,22 @@ scan_for_driver(driver_id_t start, driver_id_t end, return NULL; } +/*! + Return the value associatied with key. NULL is returned if obj is NULL + or "key" does not exist. + */ +CDText_data_t * +cdio_cdtext_query (const CdIo *obj) +{ + if (obj == NULL) return NULL; + + if (obj->op.get_arg) { + return obj->op.cdtext_query (obj->env); + } else { + return NULL; + } +} + const char * cdio_driver_describe(driver_id_t driver_id) { diff --git a/lib/cdio_private.h b/lib/cdio_private.h index a0c864e9..0bc37e4a 100644 --- a/lib/cdio_private.h +++ b/lib/cdio_private.h @@ -1,5 +1,5 @@ /* - $Id: cdio_private.h,v 1.24 2004/06/26 00:39:01 rocky Exp $ + $Id: cdio_private.h,v 1.25 2004/07/08 01:28:00 rocky Exp $ Copyright (C) 2003, 2004 Rocky Bernstein @@ -29,6 +29,7 @@ #endif #include +#include #ifdef __cplusplus extern "C" { @@ -39,6 +40,12 @@ extern "C" { typedef struct { + /*! + Return an allocated structure containing CDTEXT information found. + NULL is returned if there was a problem. + */ + CDText_data_t * (*cdtext_query) (void *env); + /*! Eject media in CD drive. If successful, as a side effect we also free obj. Return 0 if success and 1 for failure.