pkgsrc/audio/cdparanoia/patches/patch-cn

273 lines
6.7 KiB
Text
Raw Normal View History

$NetBSD: patch-cn,v 1.1 2006/09/03 17:13:30 ben Exp $
--- /dev/null 2006-09-03 09:28:05.000000000 -0700
+++ interface/osx_interface.c 2006-09-03 09:35:39.000000000 -0700
@@ -0,0 +1,267 @@
+/******************************************************************
+ * CopyPolicy: GNU Public License 2 applies
+ * Copyright (C) 1998 Monty xiphmont@mit.edu
+ ******************************************************************/
+
+#include <math.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <paths.h>
+#include <fcntl.h>
+#include <sys/syslimits.h>
+
+#include "osx_interface.h"
+#include "utils.h"
+
+char *osx_bsd_device_for_media(io_object_t media)
+{
+ char buf[PATH_MAX];
+ size_t dev_path_length;
+ CFTypeRef str_bsd_path;
+ char *result;
+
+ str_bsd_path = IORegistryEntryCreateCFProperty(media,
+ CFSTR(kIOBSDNameKey), kCFAllocatorDefault, 0);
+
+ if(str_bsd_path == NULL) {
+ return NULL;
+ }
+
+ snprintf(buf, sizeof(buf), "%s%c", _PATH_DEV, 'r' );
+ dev_path_length = strlen(buf);
+
+ if (CFStringGetCString(str_bsd_path,
+ buf + dev_path_length,
+ sizeof(buf) - dev_path_length,
+ kCFStringEncodingASCII)) {
+ result = strdup(buf);
+ } else {
+ result = NULL;
+ }
+ CFRelease(str_bsd_path);
+ return result;
+}
+
+int osx_enumerate_devices(cdrom_drive *d,
+ int (*device_found)(cdrom_drive *, io_object_t, void *),
+ void *data)
+{
+ kern_return_t ret;
+ mach_port_t port;
+ int drives = 0;
+ CFMutableDictionaryRef classes_to_match;
+ kern_return_t kern_result;
+ io_iterator_t media_iterator;
+ io_object_t next_media;
+
+ /* get port for IOKit communication */
+ if ((ret = IOMasterPort(MACH_PORT_NULL, &port)) != KERN_SUCCESS) {
+ cderror(d,"099: IOMasterPort fail\n");
+ return -1;
+ }
+
+ classes_to_match = IOServiceMatching(kIOCDMediaClass);
+ if(classes_to_match == NULL) {
+ cderror(d,"099: IOServiceMatching: NULL\n");
+ return -1;
+ }
+
+ CFDictionarySetValue(classes_to_match, CFSTR(kIOMediaEjectableKey),
+ kCFBooleanTrue);
+
+ kern_result = IOServiceGetMatchingServices(port, classes_to_match,
+ &media_iterator);
+ if (kern_result != KERN_SUCCESS) {
+ cderror(d,"099: IOServiceGetMatchingServices fail\n");
+ return -1;
+ }
+
+ while (1) {
+ drives++;
+ next_media = IOIteratorNext(media_iterator);
+ if (next_media == 0) {
+ break;
+ }
+
+ if (!device_found(d, next_media, data))
+ break;
+ IOObjectRelease(next_media);
+ }
+ if (next_media) IOObjectRelease(next_media);
+ IOObjectRelease(media_iterator);
+
+ return drives;
+}
+
+static int find_first_device(cdrom_drive *d, io_object_t io, void *data)
+{
+ io_object_t *dev = (io_object_t *)data;
+ *dev = io;
+ IOObjectRetain(io);
+ return 0;
+}
+
+io_object_t osx_default_device(cdrom_drive *d)
+{
+ io_object_t io;
+ osx_enumerate_devices(d, find_first_device, (void *)&io);
+ return io;
+}
+
+int osx_read_toc(cdrom_drive *d)
+{
+ kern_return_t ret;
+ char *devname;
+ CFRange range;
+ CFIndex buf_len;
+ int leadout;
+ CFMutableDictionaryRef properties;
+ CFDataRef data;
+ int i;
+
+ devname = strrchr(d->dev, '/');
+
+ if (devname != NULL) {
+ devname++;
+ } else {
+ devname = d->dev;
+ }
+
+ if (*devname == 'r') devname++;
+
+ /* create a CF dictionary containing the TOC */
+ ret = IORegistryEntryCreateCFProperties(d->io, &properties,
+ kCFAllocatorDefault, kNilOptions);
+
+ if( ret != KERN_SUCCESS) {
+ cderror(d, "099: IORegistryEntryCreateCFProperties fail\n");
+ return -1;
+ }
+
+ /* get the TOC from the dictionary */
+ data = (CFDataRef)CFDictionaryGetValue(properties,
+ CFSTR(kIOCDMediaTOCKey));
+ if(data == NULL) {
+ cderror(d, "099: CFDictionaryGetValue fail\n");
+ return -1;
+ }
+
+ buf_len = CFDataGetLength(data) + 1;
+ range = CFRangeMake(0, buf_len);
+
+ d->raw_toc = (CDTOC *)malloc(buf_len);
+ if (d->raw_toc == NULL) {
+ cderror(d, "099: toc malloc fail\n");
+ CFRelease(properties);
+ return -1;
+ }
+ CFDataGetBytes(data, range, (u_char *)d->raw_toc);
+
+ CFRelease(properties);
+
+ d->descriptor_count = CDTOCGetDescriptorCount(d->raw_toc);
+ d->tracks = 0;
+
+ for (i = 0; i < d->descriptor_count; i++) {
+ int track_num = d->raw_toc->descriptors[i].point;
+ CDMSF msf = d->raw_toc->descriptors[i].p;
+ int start_sector = CDConvertMSFToLBA(msf);
+ if (track_num == 0xa2) {
+ leadout = i;
+ }
+ fprintf(stderr,
+ "track_num = %d start sector %d msf: %d,%d,%d\n",
+ track_num, start_sector,
+ msf.minute, msf.second, msf.frame);
+ if (track_num > 99 || track_num < 1) {
+ // e.g.:
+ // track_num = 160 start sector 4350 msf: 1,0,0
+ // track_num = 161 start sector 67350 msf: 15,0,0
+ // track_num = 162 start sector 330645 msf: 73,30,45
+
+ continue;
+ // XXX don't know what happens here. tracks 0xa0, 0xa1, 0xa2 (leadout)
+ }
+ d->disc_toc[d->tracks].bTrack = track_num;
+ d->disc_toc[d->tracks].bFlags = (d->raw_toc->descriptors[i].adr << 4) |
+ d->raw_toc->descriptors[i].control;
+ d->disc_toc[d->tracks].dwStartSector = start_sector;
+ d->tracks++;
+ }
+ d->disc_toc[d->tracks].bTrack = 0xaa;
+ d->disc_toc[d->tracks].bFlags = (d->raw_toc->descriptors[i].adr << 4) |
+ d->raw_toc->descriptors[leadout].control;
+ d->disc_toc[d->tracks].dwStartSector = CDConvertMSFToLBA(
+ d->raw_toc->descriptors[leadout].p);
+
+ return 0;
+}
+
+int osx_open_device_orig(cdrom_drive *d, io_object_t io)
+{
+ if (io == NULL) {
+ d->io = osx_default_device(d);
+ } else {
+ IOObjectRetain(io);
+ d->io = io;
+ }
+ d->dev = osx_bsd_device_for_media(d->io);
+ if (!d->dev) {
+ IOObjectRelease(d->io);
+ return -1;
+ }
+
+ d->fd = open(d->dev, O_RDONLY | O_NONBLOCK, 0);
+ d->enable_cdda = osx_enable_cdda;
+ d->read_toc = osx_read_toc;
+ d->read_audio = osx_read_audio;
+ d->set_speed = osx_set_speed;
+
+ if (d->fd == -1) {
+ free(d->dev);
+ IOObjectRelease(d->io);
+ return -1;
+ }
+
+ osx_read_toc(d);
+
+ d->nsectors = 32;
+ d->opened = 1;
+ return 0;
+}
+
+int osx_open_device(cdrom_drive *d)
+{
+ osx_open_device_orig(d, NULL);
+}
+
+int osx_set_speed(cdrom_drive *d, int speed)
+{
+ return 0;
+}
+
+int osx_enable_cdda(cdrom_drive *d, int enable)
+{
+ return 0;
+}
+
+long osx_read_audio(cdrom_drive *d, void *buf, long begin, long sectors)
+{
+ dk_cd_read_t cd_read;
+
+ // fprintf(stderr, "read_audio %p, %d, %d\n", buf, begin, sectors);
+
+ memset(&cd_read, 0, sizeof(cd_read));
+
+ cd_read.offset = begin * kCDSectorSizeCDDA;
+ cd_read.sectorArea = kCDSectorAreaUser;
+ cd_read.sectorType = kCDSectorTypeCDDA;
+
+ cd_read.buffer = buf;
+ cd_read.bufferLength = kCDSectorSizeCDDA * sectors;
+
+ if( ioctl(d->fd, DKIOCCDREAD, &cd_read) == -1) {
+ return 0;
+ }
+ return cd_read.bufferLength / kCDSectorSizeCDDA;
+}