~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to doc/kscd/workman-docs/html/porting.html

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<html>
 
2
<head>
 
3
<!-- @(#)porting.html   1.1 02 Jun 1995 -->
 
4
<title>WorkMan porting notes</title>
 
5
</head>
 
6
 
 
7
<body>
 
8
<h1>Porting notes</h1>
 
9
 
 
10
<p>
 
11
Porting WorkMan to a new platform is a two-step process.  The first step
 
12
is to get the XView toolkit, version 3.0 or higher, running on your system.
 
13
If you're lucky, someone else has already done so.  The alt.toolkits.xview
 
14
and comp.windows.open-look newsgroups are good places to find out whether
 
15
XView exists for your system.
 
16
 
 
17
<p>
 
18
Once you have XView installed, you can work on porting WorkMan itself.
 
19
If your system has builtin libraries for manipulating audio CDs, you can
 
20
use them.  Or you can use your system's user-level SCSI interface, if any.
 
21
(Or both!)
 
22
 
 
23
<p>
 
24
All of the user interface modules ought to compile without modification.
 
25
For the most part they're just standard C and documented XView calls.
 
26
 
 
27
<p>
 
28
The platform-dependent code in WorkMan is in source files named plat_xxx.c,
 
29
where xxx is the platform name.  If you look at a directory listing you'll
 
30
see that there are files like this for Sun, HP, Linux, and other platforms
 
31
already.  Each of these files (called "platform modules") contains a set of
 
32
well-defined functions for controlling and getting information from a CD-ROM
 
33
drive.  You'll find a list of those functions below.  Ordinarily, porting
 
34
WorkMan is simply a matter of writing those functions for your platform,
 
35
and you can usually use one of the existing platform modules as a starting
 
36
point.
 
37
 
 
38
<p>
 
39
WorkMan supports the notion of running any kind of drive on any platform,
 
40
assuming the platform has facilities for sending arbitrary SCSI commands
 
41
from user processes.  To this end, you'll also find "drive modules" named
 
42
drv_xxx.c.  Each drive module contains replacement functions along the
 
43
lines of the functions in the platform modules; these replacement functions
 
44
are called when the drive doesn't respond to generic requests or when
 
45
something unusual needs to be done.  For instance, the Sony CDU-8012 (also
 
46
known as the SunCD drive) has a weird volume scale, so we need to do a
 
47
transformation on the volume setting before passing it to the drive.  But
 
48
other than that, the drive responds to generic CD-ROM commands, so
 
49
drv_sony.c only has code relating to volume control.
 
50
 
 
51
<p>
 
52
Implementing drive modules is fairly simple, but usually isn't necessary
 
53
so it won't be discussed here.  Mail me if you need to do it.
 
54
 
 
55
<p>
 
56
Here are the functions a platform module needs to implement.  All functions
 
57
should return integers.  Unless otherwise noted, they should return 0 on
 
58
okay status, -1 on an error condition.
 
59
 
 
60
<p>
 
61
The first parameter of each function is a pointer to a wm_drive structure.
 
62
You'll find it defined in "struct.h".  It's discussed after the function call
 
63
list.  You will probably find it helpful to look at one of the existing
 
64
platform modules while reading this list.  The Sun module is one of the
 
65
simpler ones.
 
66
 
 
67
<p>
 
68
<dl>
 
69
<dt>
 
70
wmcd_open(struct wm_drive *d)
 
71
<dd>
 
72
        Figure out the drive type and fill in pointers to the rest of the
 
73
        routines listed here.  This routine should set up the device to
 
74
        receive CD-ROM commands if necessary.  If the wm_drive structure
 
75
        says the drive is already open, this routine should return 0 --
 
76
        in other words, it shouldn't hurt to call wmcd_open ten times
 
77
        in a row.  If the drive couldn't be opened yet, or initialization
 
78
        couldn't be performed yet, the function should clean up and
 
79
        return 1; it will be called again after a short delay.  A common
 
80
        example is an open() call failing because there's no CD in the
 
81
        drive.
 
82
 
 
83
        <p>
 
84
        wmcd_open() should determine the drive type if possible.  If the
 
85
        wm_scsi() function has been implemented, it can simply call
 
86
        wm_scsi_get_drive_type() (which is in scsi.c) to retrieve the
 
87
        necessary information.  Then find_drive_struct() (from cdrom.c)
 
88
        should be called to look up the drive from the list of drive
 
89
        modules; it returns a pointer to a wm_drive structure, which
 
90
        should be copied into the buffer pointed to by the "d" parameter.
 
91
        Finally, the drive init function should be called.
 
92
 
 
93
        <p>
 
94
        Some systems can't determine the drive type at all, for instance
 
95
        because the CD-ROM drive can only be accessed through a limited
 
96
        set of function calls.  In that case, just pass empty strings
 
97
        to find_drive_struct() and it'll return a wm_drive structure
 
98
        pointing to the generic platform module routines.
 
99
 
 
100
<p>
 
101
<dt>
 
102
wm_scsi(struct wm_drive *d, unsigned char *cdb, int cdblen,
 
103
                unsigned char *buf, int len, int getdata)
 
104
<dd>
 
105
        Send a command to the SCSI device referenced by the wm_drive
 
106
        structure.  A CDB of appropriate size is passed in, as is a data
 
107
        buffer.  If "getdata" is true, read some data into the buffer in
 
108
        response to the command.  Otherwise the buffer might contain some
 
109
        data to be written out as part of the command.  "buf" can be
 
110
        NULL if the caller doesn't want to pass in or receive any data.
 
111
        Return -1 if the command doesn't complete successfully.  If your
 
112
        system doesn't support SCSI passthrough, this function should just
 
113
        return -1 without doing anything else.
 
114
 
 
115
</dl>
 
116
 
 
117
<p>
 
118
The following functions can be overridden by drive modules, as they're
 
119
always called indirectly via the wm_drive structure.
 
120
 
 
121
<p>
 
122
<dl>
 
123
<dt>
 
124
gen_init(struct wm_drive *d)
 
125
<dd>
 
126
        Initialize whatever drive-specific settings are required.  For the
 
127
        platform module this is usually just { return (0); } since any
 
128
        platform-specific initialization should be performed in wmcd_open(),
 
129
        but the function needs to be defined.
 
130
 
 
131
<p>
 
132
<dt>
 
133
gen_get_trackcount(struct wm_drive *d, int *tracks)
 
134
<dd>
 
135
        Store the number of tracks on the CD in *tracks.
 
136
 
 
137
<p>
 
138
<dt>
 
139
gen_get_cdlen(struct wm_drive *d, int *frames)
 
140
<dd>
 
141
        Store the total number of frames on the CD in *frames.
 
142
 
 
143
<p>
 
144
<dt>
 
145
gen_get_trackinfo(struct wm_drive *d, int track, int *data, int *startframe)
 
146
<dd>
 
147
        Get the starting frame number and type (1 = data track, 0 = audio) of
 
148
        a particular track.  Tracks are numbered starting at 1, as on the CD.
 
149
 
 
150
<p>
 
151
<dt>
 
152
gen_get_drive_status(struct wm_drive *d, enum mode oldmode, enum mode *mode,
 
153
                        int *pos, int *track, int *index)
 
154
<dd>
 
155
        Get the current status of the drive.  Mode is one of PLAYING, PAUSED,
 
156
        TRACK_DONE, STOPPED, and EJECTED, as is oldmode (which will be the
 
157
        previous mode value returned by the routine.)  The other parameters
 
158
        are filled in if the drive is playing or paused: the absolute position
 
159
        in frames, the track number, and the index number.
 
160
 
 
161
<p>
 
162
<dt>
 
163
gen_get_volume(struct wm_drive *d, int *left, int *right)
 
164
<dd>
 
165
        Get the current volume settings for the left and right channels, or
 
166
        -1 if that information can't be read from the drive.  Values range
 
167
        from 0 to 100 on a linear scale.
 
168
 
 
169
<p>
 
170
<dt>
 
171
gen_set_volume(struct wm_drive *d, int left, int right)
 
172
<dd>
 
173
        Set the current volume for each channel.  Values are from 0 to 100,
 
174
        on the same linear scale as returned by gen_get_volume().
 
175
 
 
176
<p>
 
177
<dt>
 
178
gen_pause(struct wm_drive *d)
 
179
<dd>
 
180
        Pause the CD.
 
181
 
 
182
<p>
 
183
<dt>
 
184
gen_resume(struct wm_drive *d)
 
185
<dd>
 
186
        Resume playing the CD after a pause.
 
187
 
 
188
<p>
 
189
<dt>
 
190
gen_stop(struct wm_drive *d)
 
191
<dd>
 
192
        Stop the CD if it's playing or paused.
 
193
 
 
194
<p>
 
195
<dt>
 
196
gen_play(struct wm_drive *d, int start, int end)
 
197
<dd>
 
198
        Play a stretch of the CD.  Both times are in frames.  This can return
 
199
        negative values other than -1 if playing a CD is a multi-step process,
 
200
        e.g. a "start motor" command followed by a "play audio" command.
 
201
 
 
202
<p>
 
203
<dt>
 
204
gen_eject(struct wm_drive *d)
 
205
<dd>
 
206
        Eject the CD.  Return -3 if the CD can't be ejected because it
 
207
        contains a mounted filesystem.
 
208
 
 
209
</dl>
 
210
 
 
211
<p>
 
212
The wm_drive structure has at least the following elements:
 
213
 
 
214
<pre>struct wm_drive {
 
215
        int     fd;             /* File descriptor, if used by platform */
 
216
        char    vendor[16];     /* Vendor name */
 
217
        char    model[24];      /* Drive model */
 
218
        void    *aux;           /* Pointer to optional platform-specific info */
 
219
        void    *daux;          /* Pointer to optional drive-specific info */
 
220
 
 
221
        int     (*init)();
 
222
        int     (*get_trackcount)();
 
223
        int     (*get_cdlen)();
 
224
        int     (*get_trackinfo)();
 
225
        int     (*get_drive_status)();
 
226
        int     (*get_volume)();
 
227
        int     (*set_volume)();
 
228
        int     (*pause)();
 
229
        int     (*resume)();
 
230
        int     (*stop)();
 
231
        int     (*play)();
 
232
        int     (*eject)();
 
233
}</pre>
 
234
 
 
235
<p>
 
236
The "fd" and/or "aux" elements should be filled in by the wmcd_open()
 
237
function after find_drive_struct() is called.  The "fd" element is for an
 
238
open file descriptor pointing to the drive, though if your platform doesn't
 
239
use file descriptors to refer to CD-ROM drives (e.g. the BSD/386 platform,
 
240
whose CD library uses structure pointers) you can use the "fd" element for
 
241
something else or ignore it completely.
 
242
 
 
243
<p>
 
244
The "aux" element should be used to point to any state information you
 
245
need to keep across calls to these functions.  Since WorkMan may eventually
 
246
support controlling multiple drives simultaneously, you should not use
 
247
global variables to keep per-drive state.  Define a structure for whatever
 
248
state you need, and point "aux" to it.  You can get at it in any of the
 
249
routines since they are all passed the wm_drive structure you fill in in
 
250
wmcd_open().  On many platforms, "aux" isn't needed.
 
251
 
 
252
<p>
 
253
The "daux" element is reserved for use in drive modules.
 
254
 
 
255
<p>
 
256
If you have questions, don't hesitate to send me E-mail.  I want to see
 
257
WorkMan as widely ported as possible.
 
258
 
 
259
<p>
 
260
-Steven Grimm
 
261
<a href="mailto:koreth@hyperion.com">&lt;koreth@hyperion.com&gt;</a>
 
262
 
 
263
<p>
 
264
<hr>
 
265
<a href="index.html">To the WorkMan home page</a>
 
266
 
 
267
<h5>Last update: 02 Jun 1995</h5>
 
268
 
 
269
</body>
 
270
</html>