From: Christian P. <cp...@us...> - 2005-01-31 11:09:07
|
Update of /cvsroot/pclasses/pclasses2/src/System In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5290/src/System Added Files: CdRomDevice.linux.cpp Log Message: Added CdRomDevice. --- NEW FILE: CdRomDevice.linux.cpp --- /*************************************************************************** * Copyright (C) 2005 by Christian Prochnow * * cp...@se... * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library 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 Library 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. * ***************************************************************************/ #include "pclasses/System/CdRomDevice.h" #include <sys/ioctl.h> #include <linux/cdrom.h> #include <errno.h> namespace P { namespace System { CdRomDevice::CdRomDevice(const std::string& path, AccessMode access, ShareMode share) throw(IO::IOError) : StorageDevice(path, access, share) { } CdRomDevice::~CdRomDevice() throw() { } CdRomDevice::DriveStatus CdRomDevice::driveStatus() throw(IO::IOError) { int ret = ::ioctl((int)handle(), CDROM_DRIVE_STATUS, CDSL_CURRENT); if(ret == -1) throw IO::IOError(errno, "ioctl error on device", P_SOURCEINFO); DriveStatus status; switch(ret) { case CDS_NO_DISC: status = NoDisc; break; case CDS_TRAY_OPEN: status = TrayOpen; break; case CDS_DRIVE_NOT_READY: status = DriveNotReady; break; case CDS_DISC_OK: status = DiscOk; break; case CDS_NO_INFO: /* fall through */ default: status = NoInfo; } return status; } CdRomDevice::DiscStatus CdRomDevice::discStatus() throw(IO::IOError) { int ret = ::ioctl((int)handle(), CDROM_DISC_STATUS, CDSL_CURRENT); if(ret == -1) throw IO::IOError(errno, "ioctl error on device", P_SOURCEINFO); DiscStatus status; switch(ret) { case CDS_AUDIO: status = DiscAudio; break; case CDS_DATA_1: status = DiscData1; break; case CDS_DATA_2: status = DiscData2; break; case CDS_XA_2_1: status = DiscXA21; break; case CDS_XA_2_2: status = DiscXA22; break; case CDS_MIXED: status = DiscMixed; break; case CDS_NO_DISC: case CDS_NO_INFO: /* fall through */ default: status = DiscUnknown; } return status; } void CdRomDevice::play(uint8_t startMin, uint8_t startSec, uint8_t startFrame, uint8_t endMin, uint8_t endSec, uint8_t endFrame) throw(IO::IOError) { struct cdrom_msf msf; msf.cdmsf_min0 = startMin; msf.cdmsf_sec0 = startSec; msf.cdmsf_frame0 = startFrame; msf.cdmsf_min1 = endMin; msf.cdmsf_sec1 = endSec; msf.cdmsf_frame1 = endFrame; int ret = ::ioctl((int)handle(), CDROMPLAYMSF, (void*)&msf); if(ret == -1) throw IO::IOError(errno, "ioctl error on device", P_SOURCEINFO); } void CdRomDevice::play(const Track& trk) throw(IO::IOError) { } void CdRomDevice::stop() throw(IO::IOError) { int ret = ::ioctl((int)handle(), CDROMSTOP); if(ret == -1) throw IO::IOError(errno, "ioctl error on device", P_SOURCEINFO); } void CdRomDevice::eject() throw(IO::IOError) { int ret = ::ioctl((int)handle(), CDROMEJECT); if(ret == -1) throw IO::IOError(errno, "ioctl error on device", P_SOURCEINFO); } void CdRomDevice::pause() throw(IO::IOError) { int ret = ::ioctl((int)handle(), CDROMPAUSE); if(ret == -1) throw IO::IOError(errno, "ioctl error on device", P_SOURCEINFO); } void CdRomDevice::resume() throw(IO::IOError) { int ret = ::ioctl((int)handle(), CDROMRESUME); if(ret == -1) throw IO::IOError(errno, "ioctl error on device", P_SOURCEINFO); } CdRomDevice::TrackList CdRomDevice::readTOC() throw(IO::IOError) { struct cdrom_tochdr hdr; int ret = ::ioctl((int)handle(), CDROMREADTOCHDR, (void*)&hdr); if(ret == -1) throw IO::IOError(errno, "ioctl error on device", P_SOURCEINFO); unsigned int num_tracks = hdr.cdth_trk1; struct cdrom_tocentry* toc_entries = new cdrom_tocentry[num_tracks + 1]; unsigned int ti = 0; TrackList toc; for(int track=hdr.cdth_trk0; track <= hdr.cdth_trk1; ++track) { toc_entries[ti].cdte_track = track; toc_entries[ti].cdte_format = CDROM_LBA; ret = ::ioctl((int)handle(), CDROMREADTOCENTRY, &toc_entries[ti++]); if(ret == -1) throw IO::IOError(errno, "ioctl error on device", P_SOURCEINFO); } // read lead-out ... toc_entries[ti].cdte_track = CDROM_LEADOUT; toc_entries[ti].cdte_format = CDROM_LBA; ret = ::ioctl((int)handle(), CDROMREADTOCENTRY, &toc_entries[ti++]); if(ret == -1) throw IO::IOError(errno, "ioctl error on device", P_SOURCEINFO); unsigned int i = 0; for(i = 1; i < ti; ++i); { toc.push_back(Track(i, toc_entries[i-1].cdte_ctrl & CDROM_DATA_TRACK ? Track::Data : Track::Audio, toc_entries[i-1].cdte_addr.lba)); } return toc; } void lba2msf(size_t lba, uint8_t *msf) { lba += CD_MSF_OFFSET; // msf addressing starts a lba=150 lba &= 0xffffff; // only 24bit ... msf[0] = lba / (CD_SECS*CD_FRAMES); lba %= CD_SECS*CD_FRAMES; msf[1] = lba / CD_FRAMES; msf[2] = lba % CD_FRAMES; } CdRomDevice::Track::Track(unsigned int num, Type type, size_t lba) : _num(num), _type(type), _lba(lba) { lba2msf(lba, _msf); } CdRomDevice::Track::~Track() { } unsigned int CdRomDevice::Track::num() const throw() { return _num; } CdRomDevice::Track::Type CdRomDevice::Track::type() const throw() { return _type; } size_t CdRomDevice::Track::lba() const throw() { return _lba; } uint8_t CdRomDevice::Track::minute() const throw() { return _msf[0]; } uint8_t CdRomDevice::Track::second() const throw() { return _msf[1]; } uint8_t CdRomDevice::Track::frame() const throw() { return _msf[2]; } } // !namespace System } // !namespace P |