~ubuntu-branches/ubuntu/quantal/libkcompactdisc/quantal-updates

« back to all changes in this revision

Viewing changes to wmlib/plat_news.c

  • Committer: Package Import Robot
  • Author(s): Philip Muškovac
  • Date: 2012-05-26 15:25:35 UTC
  • Revision ID: package-import@ubuntu.com-20120526152535-60v997qsp1solymv
Tags: upstream-4.8.80a
Import upstream version 4.8.80a

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of WorkMan, the civilized CD player library
 
3
 * Copyright (C) 1991-1997 by Steven Grimm <koreth@midwinter.com>
 
4
 * Copyright (C) by Dirk Försterling <milliByte@DeathsDoor.com>
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Library General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2 of the License, or (at your option) any later version.
 
10
 *
 
11
 * This library is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * Library General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Library General Public
 
17
 * License along with this library; if not, write to the Free
 
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
19
 *
 
20
 *
 
21
 * Sony NEWS-specific drive control routines.
 
22
 */
 
23
 
 
24
#if defined( __sony_news) || defined(sony_news)
 
25
 
 
26
#include <errno.h>
 
27
#include <stdio.h>
 
28
#include <fcntl.h>
 
29
#include <ustat.h>
 
30
#include <CD.h>
 
31
#include <sys/types.h>
 
32
#include <sys/param.h>
 
33
#include <sys/stat.h>
 
34
#include <sys/time.h>
 
35
 
 
36
#include "include/wm_config.h"
 
37
#include "include/wm_struct.h"
 
38
#include "include/wm_cdtext.h"
 
39
 
 
40
#define WM_MSG_CLASS WM_MSG_CLASS_PLATFORM
 
41
 
 
42
void *malloc();
 
43
char *strchr();
 
44
 
 
45
extern int intermittent_dev;
 
46
 
 
47
int     min_volume = 128;
 
48
int     max_volume = 255;
 
49
 
 
50
/*
 
51
 * Initialize the drive.  A no-op for the generic driver.
 
52
 */
 
53
int
 
54
gen_init( struct wm_drive *d )
 
55
{
 
56
        return 0;
 
57
} /* gen_init() */
 
58
 
 
59
/*
 
60
 * Open the CD device and figure out what kind of drive is attached.
 
61
 */
 
62
int
 
63
gen_open( struct wm_drive *d )
 
64
{
 
65
        if (d->fd > -1) {               /* Device already open? */
 
66
                wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "gen_open(): [device is open (fd=%d)]\n", d->fd);
 
67
                return 0;
 
68
    }
 
69
 
 
70
        intermittent_dev = 1;
 
71
 
 
72
        if ((d->fd = CD_Open(d->cd_device, 0)) < 0) {
 
73
                /* Solaris 2.2 volume manager moves links around */
 
74
                if (errno == ENOENT && intermittent_dev)
 
75
                        return 0;
 
76
 
 
77
        if (errno == EACCES)
 
78
            return -EACCES;
 
79
        else if (errno != EIO)  /* defined at top */
 
80
                return -6;
 
81
 
 
82
                /* No CD in drive. */
 
83
                return 1;
 
84
    }
 
85
 
 
86
        return 0;
 
87
} /* gen_open() */
 
88
 
 
89
/*
 
90
 * Pass SCSI commands to the device.
 
91
 */
 
92
int
 
93
gen_scsi(struct wm_drive *d, unsigned char *cdb, int cdblen,
 
94
        unsigned char *buf, int buflen, int getreply)
 
95
{
 
96
        /* NEWS can't do SCSI passthrough... or can it? */
 
97
        return -1;
 
98
} /* gen_scsi() */
 
99
 
 
100
int
 
101
gen_close( struct wm_drive *d )
 
102
{
 
103
        int ret = 0;
 
104
        if(d->fd != -1) {
 
105
                wm_lib_message(WM_MSG_LEVEL_DEBUG|WM_MSG_CLASS, "closing the device.\n");
 
106
                ret = CD_Close(d->fd);
 
107
                d->fd = -1;
 
108
                wm_susleep(3000000);
 
109
        }
 
110
        return ret;
 
111
}
 
112
 
 
113
/*
 
114
 * Get the current status of the drive: the current play mode, the absolute
 
115
 * position from start of disc (in frames), and the current track and index
 
116
 * numbers if the CD is playing or paused.
 
117
 */
 
118
int
 
119
gen_get_drive_status( struct wm_drive *d, int oldmode,
 
120
                      int *mode, int *pos, int *track, int *index)
 
121
{
 
122
        struct CD_Status                sc;
 
123
 
 
124
        /* If we can't get status, the CD is ejected, so default to that. */
 
125
        *mode = WM_CDM_EJECTED;
 
126
 
 
127
        /* Is the device open? */
 
128
        if (d->fd < 0) {
 
129
                switch (d->proto.open(d)) {
 
130
        case -1:        /* error */
 
131
                        return -1;
 
132
 
 
133
        case 1:         /* retry */
 
134
                        return 0;
 
135
        }
 
136
    }
 
137
 
 
138
  /* Disc is ejected.  Close the device. */
 
139
        if (CD_GetStatus(d->fd, &sc)) {
 
140
                gen_close(d);
 
141
                return 0;
 
142
    }
 
143
 
 
144
        switch (sc.status) {
 
145
        case CDSTAT_PLAY:
 
146
                *mode = WM_CDM_PLAYING;
 
147
                break;
 
148
 
 
149
        case CDSTAT_PAUSE:
 
150
                if (oldmode == WM_CDM_PLAYING || oldmode == WM_CDM_PAUSED)
 
151
                        *mode = WM_CDM_PAUSED;
 
152
        else
 
153
                *mode = WM_CDM_STOPPED;
 
154
        break;
 
155
 
 
156
        case CDSTAT_STOP:
 
157
                if (oldmode == WM_CDM_PLAYING) {
 
158
                        *mode = WM_CDM_TRACK_DONE;      /* waiting for next track. */
 
159
                        break;
 
160
                }
 
161
                /* fall through */
 
162
 
 
163
        default:
 
164
                *mode = WM_CDM_STOPPED;
 
165
                break;
 
166
        }
 
167
 
 
168
        switch(*mode) {
 
169
        case WM_CDM_PLAYING:
 
170
        case WM_CDM_PAUSED:
 
171
                *track = sc.tno;
 
172
                *index = sc.index;
 
173
                *pos = sc.baddr;
 
174
                break;          
 
175
        }
 
176
 
 
177
        return 0;
 
178
} /* gen_get_drive_status() */
 
179
 
 
180
/*
 
181
 * Get the number of tracks on the CD.
 
182
 */
 
183
int
 
184
gen_get_trackcount(struct wm_drive *d, int *tracks)
 
185
{
 
186
        struct CD_Capacity cc;
 
187
 
 
188
        if (CD_GetCapacity(d->fd, &cc))
 
189
        return -1;
 
190
 
 
191
        *tracks = cc.etrack - 1;
 
192
        return 0;
 
193
} /* gen_get_trackcount() */
 
194
 
 
195
/*
 
196
 * Get the start time and mode (data or audio) of a track.
 
197
 */
 
198
int
 
199
gen_get_trackinfo( struct wm_drive *d, int track, int *data, int *startframe )
 
200
{
 
201
        struct CD_TOCinfo hdr;
 
202
        struct CD_TOCdata ent;
 
203
 
 
204
        hdr.strack = track;
 
205
        hdr.ntrack = 1;
 
206
        hdr.data = &ent;
 
207
        if (CD_ReadTOC(d->fd, &hdr))
 
208
                return (-1);
 
209
 
 
210
        *data = (ent.control & 4) ? 1 : 0;
 
211
        *startframe = ent.baddr;
 
212
 
 
213
        return 0;
 
214
} /* gen_get_trackinfo */
 
215
 
 
216
/*
 
217
 * Get the number of frames on the CD.
 
218
 */
 
219
int
 
220
gen_get_cdlen( struct wm_drive *d, int *frames )
 
221
{
 
222
        int tmp;
 
223
 
 
224
        if ((d->get_trackcount)(d, &tmp))
 
225
        return -1;
 
226
 
 
227
        return gen_get_trackinfo(d, tmp + 1, &tmp, frames);
 
228
} /* gen_get_cdlen() */
 
229
 
 
230
 
 
231
/*
 
232
 * Play the CD from one position to another (both in frames.)
 
233
 */
 
234
int
 
235
gen_play( struct wm_drive *d, int start, int end )
 
236
{
 
237
        struct CD_PlayAddr msf;
 
238
 
 
239
        msf.addrmode                    = CD_MSF;
 
240
        msf.addr.msf.startmsf.min       = start / (60*75);
 
241
        msf.addr.msf.startmsf.sec       = (start % (60*75)) / 75;
 
242
        msf.addr.msf.startmsf.frame     = start % 75;
 
243
        msf.addr.msf.endmsf.min         = end / (60*75);
 
244
        msf.addr.msf.endmsf.sec         = (end % (60*75)) / 75;
 
245
        msf.addr.msf.endmsf.frame       = end % 75;
 
246
 
 
247
        if (CD_Play(d->fd, &msf)) {
 
248
                wm_lib_message(WM_MSG_LEVEL_ERROR|WM_MSG_CLASS,
 
249
                        "wm_cd_play_chunk(%d,%d)\n",start,end);
 
250
                wm_lib_message(WM_MSG_LEVEL_ERROR|WM_MSG_CLASS,
 
251
                        "msf = %d:%d:%d %d:%d:%d\n",
 
252
                        msf.addr.msf.startmsf.min,
 
253
                        msf.addr.msf.startmsf.sec,
 
254
                        msf.addr.msf.startmsf.frame,
 
255
                        msf.addr.msf.endmsf.min,
 
256
                        msf.addr.msf.endmsf.sec,
 
257
                        msf.addr.msf.endmsf.frame);
 
258
                wm_lib_message(WM_MSG_LEVEL_ERROR|WM_MSG_CLASS,
 
259
                        "CD_Play");
 
260
                return -1;
 
261
    }
 
262
 
 
263
        return 0;
 
264
} /* gen_play() */
 
265
 
 
266
/*
 
267
 * Pause the CD.
 
268
 */
 
269
int
 
270
gen_pause( struct wm_drive *d )
 
271
{
 
272
        CD_Pause(d->fd);
 
273
        return 0;
 
274
} /* gen_pause() */
 
275
 
 
276
/*
 
277
 * Resume playing the CD (assuming it was paused.)
 
278
 */
 
279
int
 
280
gen_resume( struct wm_drive *d )
 
281
{
 
282
        CD_Restart(d->fd);
 
283
        return 0;
 
284
} /* gen_resume() */
 
285
 
 
286
/*
 
287
 * Stop the CD.
 
288
 */
 
289
int
 
290
gen_stop( struct wm_drive *d )
 
291
{
 
292
        CD_Stop(d->fd);
 
293
        return 0;
 
294
} /* gen_stop() */
 
295
 
 
296
/*
 
297
 * Eject the current CD, if there is one.
 
298
 */
 
299
int
 
300
gen_eject( struct wm_drive *d )
 
301
{
 
302
        struct stat stbuf;
 
303
        struct ustat ust;
 
304
 
 
305
        if (fstat(d->fd, &stbuf) != 0)
 
306
                return -2;
 
307
 
 
308
        /* Is this a mounted filesystem? */
 
309
        if (ustat(stbuf.st_rdev, &ust) == 0)
 
310
                return -3;
 
311
 
 
312
        if (CD_AutoEject(d->fd))
 
313
        return -1);
 
314
 
 
315
        /* Close the device if it needs to vanish. */
 
316
        if (intermittent_dev)
 
317
                gen_close(d);
 
318
 
 
319
        return 0;
 
320
} /* gen_eject() */
 
321
 
 
322
/*----------------------------------------*
 
323
 * Close the CD tray
 
324
 *
 
325
 * Please edit and send changes to
 
326
 * milliByte@DeathsDoor.com
 
327
 *----------------------------------------*/
 
328
int
 
329
gen_closetray(struct wm_drive *d)
 
330
{
 
331
        return -1;
 
332
} /* gen_closetray() */
 
333
 
 
334
 
 
335
/*
 
336
 * Set the volume level for the left and right channels.  Their values
 
337
 * range from 0 to 100.
 
338
 */
 
339
int
 
340
gen_set_volume( struct wm_drive *d, int left, int right)
 
341
{
 
342
        /* NEWS can't adjust volume! */
 
343
        return 0;
 
344
}
 
345
 
 
346
/*
 
347
 * Read the initial volume from the drive, if available.  Each channel
 
348
 * ranges from 0 to 100, with -1 indicating data not available.
 
349
 */
 
350
int
 
351
gen_get_volume( struct wm_drive *d, omt *left, int *right)
 
352
{
 
353
        /* Suns, HPs, Linux, NEWS can't read the volume; oh well */
 
354
        *left = *right = -1;
 
355
        return 0;
 
356
} /* gen_get_volume() */
 
357
 
 
358
#endif