a1de9be612
Add comments to patches (not always relevant) to appease pkglint Bump revision
274 lines
6.8 KiB
Text
274 lines
6.8 KiB
Text
$NetBSD: patch-cn,v 1.2 2018/09/27 15:29:06 triaxx Exp $
|
|
|
|
Interface for MacOS.
|
|
|
|
--- /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;
|
|
+}
|