Merge from vendor branch TNF:
[pkgsrcv2.git] / audio / cdparanoia / patches / patch-cn
1 $NetBSD$
2
3 --- /dev/null   2006-09-03 09:28:05.000000000 -0700
4 +++ interface/osx_interface.c   2006-09-03 09:35:39.000000000 -0700
5 @@ -0,0 +1,267 @@
6 +/******************************************************************
7 + * CopyPolicy: GNU Public License 2 applies
8 + * Copyright (C) 1998 Monty xiphmont@mit.edu
9 + ******************************************************************/
10 +
11 +#include <math.h>
12 +#include <assert.h>
13 +#include <stdlib.h>
14 +#include <paths.h>
15 +#include <fcntl.h>
16 +#include <sys/syslimits.h>
17 +
18 +#include "osx_interface.h"
19 +#include "utils.h"
20 +
21 +char *osx_bsd_device_for_media(io_object_t media)
22 +{
23 +  char buf[PATH_MAX];
24 +  size_t dev_path_length;
25 +  CFTypeRef str_bsd_path;
26 +  char *result;
27 +
28 +  str_bsd_path = IORegistryEntryCreateCFProperty(media,
29 +    CFSTR(kIOBSDNameKey), kCFAllocatorDefault, 0);
30 +
31 +  if(str_bsd_path == NULL) {
32 +    return NULL;
33 +  }
34 +
35 +  snprintf(buf, sizeof(buf), "%s%c", _PATH_DEV, 'r' );
36 +  dev_path_length = strlen(buf);
37 +
38 +  if (CFStringGetCString(str_bsd_path,
39 +        buf + dev_path_length,
40 +        sizeof(buf) - dev_path_length,
41 +        kCFStringEncodingASCII)) {
42 +    result = strdup(buf);
43 +  } else {
44 +    result = NULL;
45 +  }
46 +  CFRelease(str_bsd_path);
47 +  return result;
48 +}
49 +
50 +int osx_enumerate_devices(cdrom_drive *d,
51 +  int (*device_found)(cdrom_drive *, io_object_t, void *),
52 +  void *data)
53 +{
54 +  kern_return_t ret;
55 +  mach_port_t port;
56 +  int drives = 0;
57 +  CFMutableDictionaryRef classes_to_match;
58 +  kern_return_t kern_result;
59 +  io_iterator_t media_iterator;
60 +  io_object_t next_media;
61 +
62 +  /* get port for IOKit communication */
63 +  if ((ret = IOMasterPort(MACH_PORT_NULL, &port)) != KERN_SUCCESS) {
64 +    cderror(d,"099: IOMasterPort fail\n");
65 +    return -1;
66 +  }
67 +
68 +  classes_to_match = IOServiceMatching(kIOCDMediaClass);
69 +  if(classes_to_match == NULL) {
70 +    cderror(d,"099: IOServiceMatching: NULL\n");
71 +    return -1;
72 +  }
73 +
74 +  CFDictionarySetValue(classes_to_match, CFSTR(kIOMediaEjectableKey),
75 +    kCFBooleanTrue);
76 +
77 +  kern_result = IOServiceGetMatchingServices(port, classes_to_match,
78 +    &media_iterator);
79 +  if (kern_result != KERN_SUCCESS) {
80 +    cderror(d,"099: IOServiceGetMatchingServices fail\n");
81 +    return -1;
82 +  }
83 +
84 +  while (1) {
85 +    drives++;
86 +    next_media = IOIteratorNext(media_iterator);
87 +    if (next_media == 0) {
88 +      break;
89 +    }
90 +
91 +    if (!device_found(d, next_media, data))
92 +      break;
93 +    IOObjectRelease(next_media);
94 +  }
95 +  if (next_media) IOObjectRelease(next_media);
96 +  IOObjectRelease(media_iterator);
97 +
98 +  return drives;
99 +}
100 +
101 +static int find_first_device(cdrom_drive *d, io_object_t io, void *data)
102 +{
103 +  io_object_t *dev = (io_object_t *)data;
104 +  *dev = io;
105 +  IOObjectRetain(io);
106 +  return 0;
107 +}
108 +
109 +io_object_t osx_default_device(cdrom_drive *d)
110 +{
111 +  io_object_t io;
112 +  osx_enumerate_devices(d, find_first_device, (void *)&io);
113 +  return io;
114 +}
115 +
116 +int osx_read_toc(cdrom_drive *d)
117 +{
118 +  kern_return_t ret;
119 +  char *devname;
120 +  CFRange range;
121 +  CFIndex buf_len;
122 +  int leadout;
123 +  CFMutableDictionaryRef properties;
124 +  CFDataRef data;
125 +  int i;
126 +
127 +  devname = strrchr(d->dev, '/');
128 +
129 +  if (devname != NULL) {
130 +    devname++;
131 +  } else {
132 +    devname = d->dev;
133 +  }
134 +
135 +  if (*devname == 'r') devname++;
136 +
137 +  /* create a CF dictionary containing the TOC */
138 +  ret = IORegistryEntryCreateCFProperties(d->io, &properties,
139 +    kCFAllocatorDefault, kNilOptions);
140 +
141 +  if( ret != KERN_SUCCESS) {
142 +    cderror(d,  "099: IORegistryEntryCreateCFProperties fail\n");
143 +    return -1;
144 +  }
145 +
146 +  /* get the TOC from the dictionary */
147 +  data = (CFDataRef)CFDictionaryGetValue(properties,
148 +    CFSTR(kIOCDMediaTOCKey));
149 +  if(data == NULL) {
150 +    cderror(d,  "099: CFDictionaryGetValue fail\n");
151 +    return -1;
152 +  }
153 +
154 +  buf_len = CFDataGetLength(data) + 1;
155 +  range = CFRangeMake(0, buf_len);
156 +
157 +  d->raw_toc = (CDTOC *)malloc(buf_len);
158 +  if (d->raw_toc == NULL) {
159 +    cderror(d,  "099: toc malloc fail\n");
160 +    CFRelease(properties);
161 +    return -1;
162 +  }
163 +  CFDataGetBytes(data, range, (u_char *)d->raw_toc);
164 +
165 +  CFRelease(properties);
166 +
167 +  d->descriptor_count = CDTOCGetDescriptorCount(d->raw_toc);
168 +  d->tracks = 0;
169 +
170 +  for (i = 0; i < d->descriptor_count; i++) {
171 +    int track_num = d->raw_toc->descriptors[i].point;
172 +    CDMSF msf = d->raw_toc->descriptors[i].p;
173 +    int start_sector = CDConvertMSFToLBA(msf);
174 +    if (track_num == 0xa2) {
175 +      leadout = i;
176 +    }
177 +    fprintf(stderr,
178 +            "track_num = %d start sector %d msf: %d,%d,%d\n",
179 +            track_num, start_sector,
180 +            msf.minute, msf.second, msf.frame);
181 +    if (track_num > 99 || track_num < 1) {
182 +      // e.g.:
183 +      // track_num = 160 start sector 4350 msf: 1,0,0
184 +      // track_num = 161 start sector 67350 msf: 15,0,0
185 +      // track_num = 162 start sector 330645 msf: 73,30,45
186 +
187 +      continue;
188 +      // XXX don't know what happens here. tracks 0xa0, 0xa1, 0xa2 (leadout)
189 +    }
190 +    d->disc_toc[d->tracks].bTrack = track_num;
191 +    d->disc_toc[d->tracks].bFlags = (d->raw_toc->descriptors[i].adr << 4) |
192 +      d->raw_toc->descriptors[i].control;
193 +    d->disc_toc[d->tracks].dwStartSector = start_sector;
194 +    d->tracks++;
195 +  }
196 +  d->disc_toc[d->tracks].bTrack = 0xaa;
197 +  d->disc_toc[d->tracks].bFlags = (d->raw_toc->descriptors[i].adr << 4) |
198 +    d->raw_toc->descriptors[leadout].control;
199 +  d->disc_toc[d->tracks].dwStartSector = CDConvertMSFToLBA(
200 +    d->raw_toc->descriptors[leadout].p);
201 +
202 +  return 0;
203 +}
204 +
205 +int osx_open_device_orig(cdrom_drive *d, io_object_t io)
206 +{
207 +  if (io == NULL) {
208 +    d->io = osx_default_device(d);
209 +  } else {
210 +    IOObjectRetain(io);
211 +    d->io = io;
212 +  }
213 +  d->dev = osx_bsd_device_for_media(d->io);
214 +  if (!d->dev) {
215 +    IOObjectRelease(d->io);
216 +    return -1;
217 +  }
218 +
219 +  d->fd = open(d->dev, O_RDONLY | O_NONBLOCK, 0);
220 +  d->enable_cdda = osx_enable_cdda;
221 +  d->read_toc = osx_read_toc;
222 +  d->read_audio = osx_read_audio;
223 +  d->set_speed = osx_set_speed;
224 +
225 +  if (d->fd == -1) {
226 +    free(d->dev);
227 +    IOObjectRelease(d->io);
228 +    return -1;
229 +  }
230 +
231 +  osx_read_toc(d);
232 +
233 +  d->nsectors = 32;
234 +  d->opened = 1;
235 +  return 0;
236 +}
237 +
238 +int osx_open_device(cdrom_drive *d)
239 +{
240 +  osx_open_device_orig(d, NULL);
241 +}
242 +
243 +int osx_set_speed(cdrom_drive *d, int speed)
244 +{
245 +  return 0;
246 +}
247 +
248 +int osx_enable_cdda(cdrom_drive *d, int enable)
249 +{
250 +  return 0;
251 +}
252 +
253 +long osx_read_audio(cdrom_drive *d, void *buf, long begin, long sectors)
254 +{
255 +  dk_cd_read_t cd_read;
256 +
257 +  // fprintf(stderr, "read_audio %p, %d, %d\n", buf, begin, sectors);
258 +
259 +  memset(&cd_read, 0, sizeof(cd_read));
260 +
261 +  cd_read.offset = begin * kCDSectorSizeCDDA;
262 +  cd_read.sectorArea = kCDSectorAreaUser;
263 +  cd_read.sectorType = kCDSectorTypeCDDA;
264 +
265 +  cd_read.buffer = buf;
266 +  cd_read.bufferLength = kCDSectorSizeCDDA * sectors;
267 +
268 +  if( ioctl(d->fd, DKIOCCDREAD, &cd_read) == -1) {
269 +    return 0;
270 +  }
271 +  return cd_read.bufferLength / kCDSectorSizeCDDA;
272 +}