diff --git a/include/cdio/device.h b/include/cdio/device.h index 05a5606c..af6108c4 100644 --- a/include/cdio/device.h +++ b/include/cdio/device.h @@ -1,5 +1,5 @@ /* -*- c -*- - $Id: device.h,v 1.20 2005/03/06 22:04:07 rocky Exp $ + $Id: device.h,v 1.21 2005/03/07 07:23:52 rocky Exp $ Copyright (C) 2005 Rocky Bernstein @@ -214,21 +214,26 @@ extern "C" { */ DRIVER_OP_BAD_PARAMETER = -5, /**< Bad parameter passed */ DRIVER_OP_BAD_POINTER = -6, /**< Bad pointer to memory area */ + DRIVER_OP_NO_DRIVER = -7, /**< Operaton called on a driver + not available on this OS */ } driver_return_code_t; /*! Close media tray in CD drive if there is a routine to do so. - @param p_cdio the CD object to be acted upon. - If the CD is ejected *p_cdio is freed and p_cdio set to NULL. + @param name of CD-ROM device to be acted upon. + driver_id is the driver to use to perform the action. If DRIVER_UNKNOWN + or DRIVER_DEVICE we'll scan for a suitable driver and set + driver_id to that on return. */ - driver_return_code_t cdio_close_tray (CdIo_t *p_cdio); + driver_return_code_t cdio_close_tray (const char *psz_device, + /*in/out*/ driver_id_t *p_driver_id); /*! Eject media in CD drive if there is a routine to do so. @param p_cdio the CD object to be acted upon. - If the CD is ejected *p_cdio is freed and p_cdio set to NULL. + If the CD is ejected *p_cdio is free'd and p_cdio set to NULL. */ driver_return_code_t cdio_eject_media (CdIo_t **p_cdio); @@ -259,6 +264,15 @@ extern "C" { */ char * cdio_get_default_device (const CdIo_t *p_cdio); + /*! + Return a string containing the default CD device if none is specified. + if p_driver_id is DRIVER_UNKNOWN or DRIVER_DEVICE + then find a suitable one set the default device for that. + + NULL is returned if we couldn't get a default device. + */ + char * cdio_get_default_device_driver (/*in/out*/ driver_id_t *p_driver_id); + /*! Return an array of device names. If you want a specific devices for a driver, give that device. If you want hardware devices, give DRIVER_DEVICE and if you want all possible devices, @@ -421,7 +435,7 @@ extern "C" { /*! Like cdio_have_xxx but uses an enumeration instead. */ bool cdio_have_driver (driver_id_t driver_id); - /*! + /* Free any resources associated with p_cdio. Call this when done using p_cdio and using CD reading/control operations. diff --git a/lib/driver/cdio_private.h b/lib/driver/cdio_private.h index d42ac717..88c6cb8d 100644 --- a/lib/driver/cdio_private.h +++ b/lib/driver/cdio_private.h @@ -1,5 +1,5 @@ /* - $Id: cdio_private.h,v 1.22 2005/03/06 11:21:52 rocky Exp $ + $Id: cdio_private.h,v 1.23 2005/03/07 07:23:52 rocky Exp $ Copyright (C) 2003, 2004, 2005 Rocky Bernstein @@ -444,12 +444,13 @@ extern "C" { const char *name; const char *describe; bool (*have_driver) (void); - CdIo *(*driver_open) (const char *psz_source_name); - CdIo *(*driver_open_am) (const char *psz_source_name, + CdIo_t *(*driver_open) (const char *psz_source_name); + CdIo_t *(*driver_open_am) (const char *psz_source_name, const char *psz_access_mode); char *(*get_default_device) (void); bool (*is_device) (const char *psz_source_name); char **(*get_devices) (void); + driver_return_code_t (*close_tray) (const char *psz_device); } CdIo_driver_t; /* The below array gives of the drivers that are currently available for @@ -472,6 +473,9 @@ extern "C" { void cdio_add_device_list(char **device_list[], const char *psz_drive, unsigned int *i_drives); + driver_return_code_t close_tray_linux (const char *psz_device); + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/lib/driver/device.c b/lib/driver/device.c index 9aa27f8b..d76234ca 100644 --- a/lib/driver/device.c +++ b/lib/driver/device.c @@ -1,5 +1,5 @@ /* - $Id: device.c,v 1.14 2005/03/06 22:04:07 rocky Exp $ + $Id: device.c,v 1.15 2005/03/07 07:23:52 rocky Exp $ Copyright (C) 2005 Rocky Bernstein @@ -95,6 +95,7 @@ CdIo_driver_t CdIo_all_drivers[CDIO_MAX_DRIVER+1] = { NULL, NULL, NULL, + NULL, NULL }, @@ -107,7 +108,8 @@ CdIo_driver_t CdIo_all_drivers[CDIO_MAX_DRIVER+1] = { &cdio_open_am_aix, &cdio_get_default_device_aix, &cdio_is_device_generic, - &cdio_get_devices_aix + &cdio_get_devices_aix, + NULL }, {DRIVER_BSDI, @@ -119,7 +121,8 @@ CdIo_driver_t CdIo_all_drivers[CDIO_MAX_DRIVER+1] = { &cdio_open_am_bsdi, &cdio_get_default_device_bsdi, &cdio_is_device_generic, - &cdio_get_devices_bsdi + &cdio_get_devices_bsdi, + NULL }, {DRIVER_FREEBSD, @@ -131,7 +134,7 @@ CdIo_driver_t CdIo_all_drivers[CDIO_MAX_DRIVER+1] = { &cdio_open_am_freebsd, &cdio_get_default_device_freebsd, &cdio_is_device_generic, - NULL + NULL, }, {DRIVER_LINUX, @@ -143,7 +146,8 @@ CdIo_driver_t CdIo_all_drivers[CDIO_MAX_DRIVER+1] = { &cdio_open_am_linux, &cdio_get_default_device_linux, &cdio_is_device_generic, - &cdio_get_devices_linux + &cdio_get_devices_linux, + &close_tray_linux }, {DRIVER_SOLARIS, @@ -155,7 +159,8 @@ CdIo_driver_t CdIo_all_drivers[CDIO_MAX_DRIVER+1] = { &cdio_open_am_solaris, &cdio_get_default_device_solaris, &cdio_is_device_generic, - &cdio_get_devices_solaris + &cdio_get_devices_solaris, + NULL }, {DRIVER_OSX, @@ -167,7 +172,8 @@ CdIo_driver_t CdIo_all_drivers[CDIO_MAX_DRIVER+1] = { &cdio_open_am_osx, &cdio_get_default_device_osx, &cdio_is_device_generic, - &cdio_get_devices_osx + &cdio_get_devices_osx, + NULL }, {DRIVER_WIN32, @@ -179,7 +185,8 @@ CdIo_driver_t CdIo_all_drivers[CDIO_MAX_DRIVER+1] = { &cdio_open_am_win32, &cdio_get_default_device_win32, &cdio_is_device_win32, - &cdio_get_devices_win32 + &cdio_get_devices_win32, + NULL }, {DRIVER_CDRDAO, @@ -191,7 +198,8 @@ CdIo_driver_t CdIo_all_drivers[CDIO_MAX_DRIVER+1] = { &cdio_open_am_cdrdao, &cdio_get_default_device_cdrdao, NULL, - &cdio_get_devices_cdrdao + &cdio_get_devices_cdrdao, + NULL }, {DRIVER_BINCUE, @@ -203,7 +211,8 @@ CdIo_driver_t CdIo_all_drivers[CDIO_MAX_DRIVER+1] = { &cdio_open_am_bincue, &cdio_get_default_device_bincue, NULL, - &cdio_get_devices_bincue + &cdio_get_devices_bincue, + NULL }, {DRIVER_NRG, @@ -215,7 +224,8 @@ CdIo_driver_t CdIo_all_drivers[CDIO_MAX_DRIVER+1] = { &cdio_open_am_nrg, &cdio_get_default_device_nrg, NULL, - &cdio_get_devices_nrg + &cdio_get_devices_nrg, + NULL } }; @@ -262,7 +272,7 @@ cdio_init(void) return false; } - for (driver_id=DRIVER_UNKNOWN; driver_id<=CDIO_MAX_DRIVER; driver_id++) { + for (driver_id=DRIVER_UNKNOWN+1; driver_id<=CDIO_MAX_DRIVER; driver_id++) { all_dp = &CdIo_all_drivers[driver_id]; if ((*CdIo_all_drivers[driver_id].have_driver)()) { *dp++ = *all_dp; @@ -292,18 +302,31 @@ cdio_destroy (CdIo_t *p_cdio) Close media tray in CD drive if there is a routine to do so. @param p_cdio the CD object to be acted upon. - If the CD is ejected *p_cdio is freed and p_cdio set to NULL. + If the CD is ejected *p_cdio is free'd and p_cdio set to NULL. */ driver_return_code_t -cdio_close_tray (CdIo_t *p_cdio) +cdio_close_tray (const char *psz_device, /*in/out*/ driver_id_t + *p_driver_id) { - if (!p_cdio) return DRIVER_OP_UNINIT; - - if (!p_cdio->op.close_tray) { - return p_cdio->op.close_tray(p_cdio->env); - } else { + if (DRIVER_UNKNOWN == *p_driver_id || DRIVER_DEVICE == *p_driver_id) { + *p_driver_id = CDIO_MIN_DEVICE_DRIVER; + + /* Scan for driver */ + for ( ; *p_driver_id<=CDIO_MAX_DRIVER; *p_driver_id++) { + if ( (*CdIo_all_drivers[*p_driver_id].have_driver)() && + *CdIo_all_drivers[*p_driver_id].close_tray ) { + return (*CdIo_all_drivers[*p_driver_id].close_tray)(psz_device); + } + } return DRIVER_OP_UNSUPPORTED; } + + /* The driver id was specified. Use that. */ + if ( (*CdIo_all_drivers[*p_driver_id].have_driver)() && + *CdIo_all_drivers[*p_driver_id].close_tray ) { + return (*CdIo_all_drivers[*p_driver_id].close_tray)(psz_device); + } + return DRIVER_OP_UNSUPPORTED; } /*! @@ -346,7 +369,7 @@ void cdio_free_device_list (char * device_list[]) /*! Return a string containing the default CD device if none is specified. - if CdIo is NULL (we haven't initialized a specific device driver), + if p_cdio is NULL (we haven't initialized a specific device driver), then find a suitable one and return the default device for that. NULL is returned if we couldn't get a default device. @@ -357,7 +380,7 @@ cdio_get_default_device (const CdIo_t *p_cdio) if (p_cdio == NULL) { driver_id_t driver_id; /* Scan for driver */ - for (driver_id=DRIVER_UNKNOWN; driver_id<=CDIO_MAX_DRIVER; driver_id++) { + for (driver_id=DRIVER_UNKNOWN+1; driver_id<=CDIO_MAX_DRIVER; driver_id++) { if ( (*CdIo_all_drivers[driver_id].have_driver)() && *CdIo_all_drivers[driver_id].get_default_device ) { return (*CdIo_all_drivers[driver_id].get_default_device)(); @@ -373,6 +396,40 @@ cdio_get_default_device (const CdIo_t *p_cdio) } } +/*! + Return a string containing the default CD device if none is specified. + if p_driver_id is DRIVER_UNKNOWN or DRIVER_DEVICE + then find a suitable one set the default device for that. + + NULL is returned if we couldn't get a default device. + */ +char * +cdio_get_default_device_driver (/*in/out*/ driver_id_t *p_driver_id) +{ + if (DRIVER_UNKNOWN == *p_driver_id || DRIVER_DEVICE == *p_driver_id) { + if (DRIVER_UNKNOWN == *p_driver_id) + *p_driver_id++; + else + *p_driver_id = CDIO_MIN_DEVICE_DRIVER; + + /* Scan for driver */ + for ( ; *p_driver_id<=CDIO_MAX_DRIVER; *p_driver_id++) { + if ( (*CdIo_all_drivers[*p_driver_id].have_driver)() && + *CdIo_all_drivers[*p_driver_id].get_default_device ) { + return (*CdIo_all_drivers[*p_driver_id].get_default_device)(); + } + } + return NULL; + } + + /* The driver id was specified. Use that. */ + if ( (*CdIo_all_drivers[*p_driver_id].have_driver)() && + *CdIo_all_drivers[*p_driver_id].get_default_device ) { + return (*CdIo_all_drivers[*p_driver_id].get_default_device)(); + } + return NULL; +} + /*!Return an array of device names. If you want a specific devices, dor a driver give that device, if you want hardware devices, give DRIVER_DEVICE and if you want all possible devices, @@ -396,12 +453,12 @@ cdio_get_devices_ret (/*in/out*/ driver_id_t *p_driver_id) switch (*p_driver_id) { /* FIXME: spit out unknown to give image drivers as well. */ case DRIVER_DEVICE: - p_cdio = scan_for_driver(DRIVER_UNKNOWN, CDIO_MAX_DEVICE_DRIVER, + p_cdio = scan_for_driver(DRIVER_UNKNOWN+1, CDIO_MAX_DEVICE_DRIVER, NULL, NULL); *p_driver_id = cdio_get_driver_id(p_cdio); break; case DRIVER_UNKNOWN: - p_cdio = scan_for_driver(DRIVER_UNKNOWN, CDIO_MAX_DRIVER, NULL, NULL); + p_cdio = scan_for_driver(DRIVER_UNKNOWN+1, CDIO_MAX_DRIVER, NULL, NULL); *p_driver_id = cdio_get_driver_id(p_cdio); break; default: @@ -751,10 +808,10 @@ cdio_open_am (const char *psz_orig_source, driver_id_t driver_id, switch (driver_id) { case DRIVER_UNKNOWN: { - CdIo_t *cdio=scan_for_driver(CDIO_MIN_DRIVER, CDIO_MAX_DRIVER, - psz_source, psz_access_mode); + CdIo_t *p_cdio=scan_for_driver(CDIO_MIN_DRIVER, CDIO_MAX_DRIVER, + psz_source, psz_access_mode); free(psz_source); - return cdio; + return p_cdio; } case DRIVER_DEVICE: { diff --git a/lib/driver/gnu_linux.c b/lib/driver/gnu_linux.c index c5352c3b..7e081995 100644 --- a/lib/driver/gnu_linux.c +++ b/lib/driver/gnu_linux.c @@ -1,5 +1,5 @@ /* - $Id: gnu_linux.c,v 1.6 2005/03/06 22:53:50 rocky Exp $ + $Id: gnu_linux.c,v 1.7 2005/03/07 07:23:52 rocky Exp $ Copyright (C) 2001 Herbert Valerio Riedel Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein @@ -27,7 +27,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: gnu_linux.c,v 1.6 2005/03/06 22:53:50 rocky Exp $"; +static const char _rcsid[] = "$Id: gnu_linux.c,v 1.7 2005/03/07 07:23:52 rocky Exp $"; #include @@ -313,19 +313,6 @@ audio_stop_linux (void *p_user_data) return ioctl(p_env->gen.fd, CDROMSTOP); } -/*! - Close tray on CD-ROM. - - @param p_user_data the CD object to be acted upon. - -*/ -static driver_return_code_t -close_tray_linux (void *p_user_data) -{ - const _img_private_t *p_env = p_user_data; - return ioctl(p_env->gen.fd, CDROMCLOSETRAY); -} - /*! Return the value associated with the key "arg". */ @@ -1316,6 +1303,54 @@ cdio_get_default_device_linux(void) return NULL; #endif /*HAVE_LINUX_CDROM*/ } + +/*! + Close tray on CD-ROM. + + @param p_user_data the CD object to be acted upon. + +*/ +driver_return_code_t +close_tray_linux (const char *psz_device) +{ +#ifdef HAVE_LINUX_CDROM + int i_rc; + int fd = open (psz_device, O_RDONLY|O_NONBLOCK); + int status; + + if ( fd > -1 ) { + if((status = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) > 0) { + switch(status) { + case CDS_TRAY_OPEN: + goto try_anyway; + break; + case CDS_DISC_OK: + cdio_info ("Tray already closed."); + i_rc = DRIVER_OP_SUCCESS; + break; + default: + cdio_info ("Unknown CD-ROM status (%d), trying anyway", status); + goto try_anyway; + } + } else { + cdio_info ("CDROM_DRIVE_STATUS failed: %s, trying anyway", + strerror(errno)); + try_anyway: + i_rc = DRIVER_OP_SUCCESS; + if((i_rc = ioctl(fd, CDROMCLOSETRAY)) != 0) { + cdio_warn ("ioctl CDROMCLOSETRAY failed: %s\n", strerror(errno)); + i_rc = DRIVER_OP_ERROR; + } + } + close(fd); + } else + i_rc = DRIVER_OP_ERROR; + return i_rc; +#else + return DRIVER_OP_NO_DRIVER; +#endif /*HAVE_LINUX_CDROM*/ +} + /*! Initialization routine. This is the only thing that doesn't get called via a function pointer. In fact *we* are the @@ -1324,7 +1359,11 @@ cdio_get_default_device_linux(void) CdIo_t * cdio_open_linux (const char *psz_source_name) { +#ifdef HAVE_LINUX_CDROM return cdio_open_am_linux(psz_source_name, NULL); +#else + return NULL; +#endif /*HAVE_LINUX_CDROM*/ } /*! @@ -1354,7 +1393,6 @@ cdio_open_am_linux (const char *psz_orig_source, const char *access_mode) .audio_resume = audio_resume_linux, .audio_set_volume = audio_set_volume_linux, .audio_stop = audio_stop_linux, - .close_tray = close_tray_linux, .eject_media = eject_media_linux, .free = cdio_generic_free, .get_arg = get_arg_linux, diff --git a/lib/driver/libcdio.sym b/lib/driver/libcdio.sym index 627f2f27..da4775d8 100644 --- a/lib/driver/libcdio.sym +++ b/lib/driver/libcdio.sym @@ -36,6 +36,7 @@ cdio_get_default_device cdio_get_default_device_bincue cdio_get_default_device_bsdi cdio_get_default_device_cdrdao +cdio_get_default_device_driver cdio_get_default_device_freebsd cdio_get_default_device_linux cdio_get_default_device_nrg