Logo Search packages:      
Sourcecode: xcfa version File versions

cd_ioctl.c

 /*
 * file      : cd_ioctl.c
 * project   : xcfa
 * with      : Gtk-2
 *
 * copyright : (C) 2003,2004,2005,2006,2007,2008,2009 by Claude Bulin
 *
 * xcfa - GTK+ implementation of the GNU shell command
 * GNU General Public License
 *
 * 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
 * OLD ADRESS:
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * NEW ADRESS:
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 */


#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gtk/gtk.h>
#include <glib/gprintf.h>

/* For Linux */
#ifdef HAVE_LINUX_CDROM_H
#include <linux/cdrom.h>
#endif

#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#include "global.h"
#include "cd_audio.h"
#include "scan_cd.h"
#include "cdtoc.h"
#include "cd_cue.h"




/*
*---------------------------------------------------------------------------
* FUNCTIONS
*---------------------------------------------------------------------------
*/


/*---------------------------------------------------
 * -   Original Routines for calculating disc-id   -
 * -   see "cddb.howto" for copyright              -
 *---------------------------------------------------
 * Retourne l'identifiant du cd
 *
 * cdtoc_cddb_sum ()
 * cdtoc_cddb_discid ()
 */
unsigned int cdioctl_cddb_sum(int n) {
      unsigned int ret;

      /* PRINT_FUNC_LF(); */
      ret = 0;
      while (n > 0) {
            ret += (n % 10);
            n /= 10;
      }
      return ret;
}
unsigned long cdioctl_cddb_discid (TIME_CD *TimeTrack, int tot_trks) {
      unsigned int i = 0;
      unsigned int t = 0;
      unsigned int n = 0;

      /*PRINT_FUNC_LF();*/
      while (i < tot_trks) {
            n = n + cdioctl_cddb_sum ((TimeTrack[ i ].SumMin * 60) + TimeTrack[ i ].SumSec);
            i++;
      }
      t = ((TimeTrack[ tot_trks ].SumMin * 60) + TimeTrack[ tot_trks ].SumSec) -
            ((TimeTrack[ 0 ].SumMin * 60) + TimeTrack[ 0 ].SumSec);

      /* Copyright WSPse
      * eMail: wsp@gmx.de
      *
      * These are the routines for cdrom I/O-handling
      * Last updated: 20/11/99
      * Updated: 2000/06/24 (BSD routines by Scott Aaron Bamford)
      *          2001/01/07 (64bit-support for CDDB-ID)
      *
      * changed for 64-bit compatibilty
      * Matthias Hensler, 2001/01/07
      */
      return ((n % 0xff) << 24 | t << 8 | tot_trks) & 0xffffffff;
      /*return ((n % 0xff) << 24 | t << 8 | tot_trks);*/
}

/* Prend les infos de base, allocmem, stock et retour
 *
 * RETURN
 *    0  OK
 *    1  PROBLEME D'ALLOCATION MEMOIRE
 *    2  CD-ROM AUDIO ABSENT DU LECTEUR
 *    3  LE CD DANS LECTEUR N'EST PAS UN CD-AUDIO
 */
gint cdioctl_read_toc (void) {
#ifdef HAVE_LINUX_CDROM_H
      /*int drive = open ("/dev/hdc", O_RDONLY | O_NONBLOCK);*/
      /*int drive = open (scancd_get_text_combo_cd (_DEVICE_), O_RDONLY | O_NONBLOCK);*/
      int    drive = open (EnteteCD.NameCD_Device, O_RDONLY | O_NONBLOCK);
      struct cdrom_tochdr tochdr;
      struct cdrom_tocentry tocentry;
      gint   retcode;
      gint   min;
      gint   i;
      gint   TempDiv;
      gint   TempMod;

#ifdef CDROMSUBCHNL
      struct cdrom_subchnl cdsc;

      /*PRINT_FUNC_LF();*/

      cdsc.cdsc_format=CDROM_MSF;

      i = ioctl(drive,CDROMSUBCHNL,&cdsc);
      if (i < 0) {
            g_print ("\nCD NON AUDIO OU ABSENT DANS LE LECTEUR\n");
            close(drive);
            /* 1  CD-ROM AUDIO ABSENT DU LECTEUR
            */
            return 2;
      }

      if(cdsc.cdsc_audiostatus &&
            (cdsc.cdsc_audiostatus<0x11||cdsc.cdsc_audiostatus>0x15)) {
            g_print ("-------------------CDROMSUBCHNL_2 = FALSE\n");
      }
#endif

#ifdef CDROM_DRIVE_STATUS
      retcode=ioctl(drive,CDROM_DRIVE_STATUS,CDSL_CURRENT);
      if(retcode != CDS_DISC_OK && retcode != CDS_NO_INFO) {
            close(drive);
            /* 1  CD-ROM AUDIO ABSENT DU LECTEUR
            */
            return 1;
      }
#endif

      i = ioctl(drive, CDROMREADTOCHDR, &tochdr);

      if ((CdToc = (CD_TOC *)g_malloc0 (sizeof (CD_TOC))) == NULL) {
            close(drive);
            cdtoc_deallocate_cd_toc ();
            /* 2  PROBLEME D'ALLOCATION MEMOIRE
            */
            return 1;
      }

      if ((CdToc->TimeTrack = (TIME_CD *)g_malloc0 (sizeof (TIME_CD) * (tochdr.cdth_trk1 + 10))) == NULL) {
            close(drive);
            cdtoc_deallocate_cd_toc ();
            /* 2  PROBLEME D'ALLOCATION MEMOIRE
            */
            return 1;
      }

      for (i = tochdr.cdth_trk0; i <= tochdr.cdth_trk1; i++) {
            tocentry.cdte_track = i;
            tocentry.cdte_format = CDROM_MSF;
            ioctl(drive, CDROMREADTOCENTRY, &tocentry);
            CdToc->TimeTrack[ i-1 ].SumMin    = tocentry.cdte_addr.msf.minute;
            CdToc->TimeTrack[ i-1 ].SumSec    = tocentry.cdte_addr.msf.second;
            CdToc->TimeTrack[ i-1 ].SumCent   = tocentry.cdte_addr.msf.frame;
            CdToc->TimeTrack[ i-1 ].SumCent += CdToc->TimeTrack[ i-1 ].SumMin * 60 * 75;
            CdToc->TimeTrack[ i-1 ].SumCent += CdToc->TimeTrack[ i-1 ].SumSec * 75;
      }

      tocentry.cdte_track = 0xAA;
      tocentry.cdte_format = CDROM_MSF;
      ioctl(drive, CDROMREADTOCENTRY, &tocentry);
      CdToc->TimeTrack[ tochdr.cdth_trk1 ].SumMin    = tocentry.cdte_addr.msf.minute;
      CdToc->TimeTrack[ tochdr.cdth_trk1 ].SumSec    = tocentry.cdte_addr.msf.second;
      CdToc->TimeTrack[ tochdr.cdth_trk1 ].SumCent  = tocentry.cdte_addr.msf.frame;
      CdToc->TimeTrack[ tochdr.cdth_trk1 ].SumCent += CdToc->TimeTrack[ tochdr.cdth_trk1 ].SumMin * 60 * 75;
      CdToc->TimeTrack[ tochdr.cdth_trk1 ].SumCent += CdToc->TimeTrack[ tochdr.cdth_trk1 ].SumSec * 75;

      close(drive);

      if (tochdr.cdth_trk1 == 1 && CdToc->TimeTrack[ 0 ].SumCent == 150) {
            /* 3  LE CD DANS LECTEUR N'EST PAS UN CD-AUDIO
            */
            return 3;
      }
      
      /*LE NOMBRE TOTAL DE PISTE : 1..n */
      CdToc->TotalTracks = tochdr.cdth_trk1;

      /*IDENTIFICATION DU CD */
      CdToc->Num_ID_CD = cdioctl_cddb_discid (CdToc->TimeTrack, tochdr.cdth_trk1);
      g_sprintf (CdToc->Str_ID_CD, "%08lx", CdToc->Num_ID_CD);

      /* DUREE TOTALE PISTES */
      min = CdToc->TimeTrack[ tochdr.cdth_trk1 ].SumCent - CdToc->TimeTrack[ 0 ].SumCent;
      CdToc->TT_Min = CdToc->TimeTrack[ CdToc->TotalTracks ].Min = (min / 60) / 75;
      CdToc->TT_Sec = CdToc->TimeTrack[ CdToc->TotalTracks ].Sec = (min / 75) % 60;
      
      /* DUREE D'ECOUTE DES PISTES */
      for (i = 0; i < CdToc->TotalTracks; i++) {
            min = CdToc->TimeTrack[ i+1 ].SumCent - CdToc->TimeTrack[ i ].SumCent;
            CdToc->TimeTrack[ i ].Min = (min / 60) / 75;
            CdToc->TimeTrack[ i ].Sec = (min / 75) % 60;
      }
      
      cdcue_alloc_base_ioctl (CdToc->TotalTracks);
      if (BaseIoctl.Datas == NULL) {
            PRINT("BaseIoctl.Datas == NULL");
            return 3;
      }
      
      for (i = 0; i < CdToc->TotalTracks; i++) {
            BaseIoctl.Datas[ i ].length = -1;
            BaseIoctl.Datas[ i ].begin  = -1;
      }

      for (i = 0; i < CdToc->TotalTracks; i++) {
            
            BaseIoctl.Datas[ i ].length = CdToc->TimeTrack[ i +1 ].SumCent - CdToc->TimeTrack[ i ].SumCent;
            TempDiv = BaseIoctl.Datas[ i ].length / 75;
            TempMod = BaseIoctl.Datas[ i ].length % 75;
            BaseIoctl.Datas[ i ].length_min  = TempDiv / 60;
            BaseIoctl.Datas[ i ].length_sec  = TempDiv % 60;
            BaseIoctl.Datas[ i ].length_cent = TempMod;
      }
      BaseIoctl.Datas[ 0 ].begin = CdToc->TimeTrack[ 0 ].SumCent % 75;
      
      for (i = 0; i < CdToc->TotalTracks; i++) {
            
            BaseIoctl.Datas[ i +1 ].begin = BaseIoctl.Datas[ i ].length + BaseIoctl.Datas[ i ].begin;
            TempDiv = BaseIoctl.Datas[ i ].begin / 75;
            TempMod = BaseIoctl.Datas[ i ].begin % 75;
            BaseIoctl.Datas[ i ].begin_min  = TempDiv / 60;
            BaseIoctl.Datas[ i ].begin_sec  = TempDiv % 60;
            BaseIoctl.Datas[ i ].begin_cent = TempMod;
      }
      BaseIoctl.Datas[ CdToc->TotalTracks ].begin  = BaseIoctl.Datas[ i ].length + BaseIoctl.Datas[ i ].begin;
      BaseIoctl.Datas[ CdToc->TotalTracks ].begin -= BaseIoctl.Datas[ 0 ].begin;
      TempDiv = BaseIoctl.Datas[ CdToc->TotalTracks ].begin / 75;
      TempMod = BaseIoctl.Datas[ CdToc->TotalTracks ].begin % 75;
      BaseIoctl.Datas[ CdToc->TotalTracks ].begin_min  = TempDiv / 60;
      BaseIoctl.Datas[ CdToc->TotalTracks ].begin_sec  = TempDiv % 60;
      BaseIoctl.Datas[ CdToc->TotalTracks ].begin_cent = TempMod;

      cdcue_print_base_ioctl ();
      
#endif
      return 0;
}


Generated by  Doxygen 1.6.0   Back to index