blob: 63c90b8950e5a7055d2bf840fc41a55a66c8313a [file] [log] [blame]
Guido van Rossum16b8f301992-04-13 18:22:53 +00001/**********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum16b8f301992-04-13 18:22:53 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum16b8f301992-04-13 18:22:53 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum16b8f301992-04-13 18:22:53 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum16b8f301992-04-13 18:22:53 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum16b8f301992-04-13 18:22:53 +000029
30******************************************************************/
31
32/* CD module -- interface to Mark Callow's and Roger Chickering's */
33 /* CD Audio Library (CD). */
34
35#include <sys/types.h>
36#include <cdaudio.h>
Sjoerd Mullender542659b1995-03-28 12:06:23 +000037/* #include <sigfpe.h> */
Guido van Rossum16b8f301992-04-13 18:22:53 +000038#include "allobjects.h"
39#include "import.h"
40#include "modsupport.h"
Guido van Rossum16b8f301992-04-13 18:22:53 +000041#include "ceval.h"
42
43#define NCALLBACKS 8
44
45typedef struct {
46 OB_HEAD
47 CDPLAYER *ob_cdplayer;
48} cdplayerobject;
49
Sjoerd Mullender46927ba1992-09-24 10:48:40 +000050static object *CdError; /* exception cd.error */
51
Guido van Rossum16b8f301992-04-13 18:22:53 +000052static object *
53CD_allowremoval(self, args)
54 cdplayerobject *self;
55 object *args;
56{
Sjoerd Mullender542659b1995-03-28 12:06:23 +000057 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +000058 return NULL;
59
60 CDallowremoval(self->ob_cdplayer);
61
62 INCREF(None);
63 return None;
64}
65
66static object *
67CD_preventremoval(self, args)
68 cdplayerobject *self;
69 object *args;
70{
Sjoerd Mullender542659b1995-03-28 12:06:23 +000071 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +000072 return NULL;
73
74 CDpreventremoval(self->ob_cdplayer);
75
76 INCREF(None);
77 return None;
78}
79
80static object *
Guido van Rossum16b8f301992-04-13 18:22:53 +000081CD_bestreadsize(self, args)
82 cdplayerobject *self;
83 object *args;
84{
Sjoerd Mullender542659b1995-03-28 12:06:23 +000085 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +000086 return NULL;
87
88 return newintobject((long) CDbestreadsize(self->ob_cdplayer));
89}
90
91static object *
92CD_close(self, args)
93 cdplayerobject *self;
94 object *args;
95{
Sjoerd Mullender542659b1995-03-28 12:06:23 +000096 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +000097 return NULL;
98
99 if (!CDclose(self->ob_cdplayer)) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000100 err_errno(CdError); /* XXX - ??? */
Guido van Rossum16b8f301992-04-13 18:22:53 +0000101 return NULL;
102 }
103 self->ob_cdplayer = NULL;
104
105 INCREF(None);
106 return None;
107}
108
109static object *
110CD_eject(self, args)
111 cdplayerobject *self;
112 object *args;
113{
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000114 CDSTATUS status;
115
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000116 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000117 return NULL;
118
119 if (!CDeject(self->ob_cdplayer)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000120 if (CDgetstatus(self->ob_cdplayer, &status) &&
121 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000122 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000123 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000124 err_setstr(CdError, "eject failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000125 return NULL;
126 }
127
128 INCREF(None);
129 return None;
130}
131
132static object *
133CD_getstatus(self, args)
134 cdplayerobject *self;
135 object *args;
136{
137 CDSTATUS status;
138
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000139 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000140 return NULL;
141
142 if (!CDgetstatus(self->ob_cdplayer, &status)) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000143 err_errno(CdError); /* XXX - ??? */
Guido van Rossum16b8f301992-04-13 18:22:53 +0000144 return NULL;
145 }
146
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000147 return mkvalue("(ii(iii)(iii)(iii)iiii)", status.state,
Guido van Rossumece6efe1992-04-15 15:56:11 +0000148 status.track, status.min, status.sec, status.frame,
149 status.abs_min, status.abs_sec, status.abs_frame,
150 status.total_min, status.total_sec, status.total_frame,
151 status.first, status.last, status.scsi_audio,
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000152 status.cur_block);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000153}
154
155static object *
156CD_gettrackinfo(self, args)
157 cdplayerobject *self;
158 object *args;
159{
160 int track;
161 CDTRACKINFO info;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000162 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000163
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000164 if (!newgetargs(args, "i", &track))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000165 return NULL;
166
167 if (!CDgettrackinfo(self->ob_cdplayer, track, &info)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000168 if (CDgetstatus(self->ob_cdplayer, &status) &&
169 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000170 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000171 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000172 err_setstr(CdError, "gettrackinfo failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000173 return NULL;
174 }
175
Guido van Rossumece6efe1992-04-15 15:56:11 +0000176 return mkvalue("((iii)(iii))",
Guido van Rossum16b8f301992-04-13 18:22:53 +0000177 info.start_min, info.start_sec, info.start_frame,
178 info.total_min, info.total_sec, info.total_frame);
179}
180
181static object *
182CD_msftoblock(self, args)
183 cdplayerobject *self;
184 object *args;
185{
186 int min, sec, frame;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000187
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000188 if (!newgetargs(args, "iii", &min, &sec, &frame))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000189 return NULL;
190
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000191 return newintobject((long) CDmsftoblock(self->ob_cdplayer,
192 min, sec, frame));
Guido van Rossum16b8f301992-04-13 18:22:53 +0000193}
194
195static object *
196CD_play(self, args)
197 cdplayerobject *self;
198 object *args;
199{
200 int start, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000201 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000202
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000203 if (!newgetargs(args, "ii", &start, &play))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000204 return NULL;
205
206 if (!CDplay(self->ob_cdplayer, start, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000207 if (CDgetstatus(self->ob_cdplayer, &status) &&
208 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000209 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000210 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000211 err_setstr(CdError, "play failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000212 return NULL;
213 }
214
215 INCREF(None);
216 return None;
217}
218
219static object *
220CD_playabs(self, args)
221 cdplayerobject *self;
222 object *args;
223{
224 int min, sec, frame, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000225 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000226
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000227 if (!newgetargs(args, "iiii", &min, &sec, &frame, &play))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000228 return NULL;
229
230 if (!CDplayabs(self->ob_cdplayer, min, sec, frame, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000231 if (CDgetstatus(self->ob_cdplayer, &status) &&
232 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000233 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000234 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000235 err_setstr(CdError, "playabs failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000236 return NULL;
237 }
238
239 INCREF(None);
240 return None;
241}
242
243static object *
244CD_playtrack(self, args)
245 cdplayerobject *self;
246 object *args;
247{
248 int start, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000249 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000250
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000251 if (!newgetargs(args, "ii", &start, &play))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000252 return NULL;
253
254 if (!CDplaytrack(self->ob_cdplayer, start, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000255 if (CDgetstatus(self->ob_cdplayer, &status) &&
256 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000257 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000258 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000259 err_setstr(CdError, "playtrack failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000260 return NULL;
261 }
262
263 INCREF(None);
264 return None;
265}
266
267static object *
268CD_playtrackabs(self, args)
269 cdplayerobject *self;
270 object *args;
271{
272 int track, min, sec, frame, play;
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000273 CDSTATUS status;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000274
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000275 if (!newgetargs(args, "iiiii", &track, &min, &sec, &frame, &play))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000276 return NULL;
277
278 if (!CDplaytrackabs(self->ob_cdplayer, track, min, sec, frame, play)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000279 if (CDgetstatus(self->ob_cdplayer, &status) &&
280 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000281 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000282 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000283 err_setstr(CdError, "playtrackabs failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000284 return NULL;
285 }
286
287 INCREF(None);
288 return None;
289}
290
291static object *
292CD_readda(self, args)
293 cdplayerobject *self;
294 object *args;
295{
296 int numframes, n;
297 object *result;
298
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000299 if (!newgetargs(args, "i", &numframes))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000300 return NULL;
301
302 result = newsizedstringobject(NULL, numframes * sizeof(CDFRAME));
303 if (result == NULL)
304 return NULL;
305
306 n = CDreadda(self->ob_cdplayer, (CDFRAME *) getstringvalue(result), numframes);
307 if (n == -1) {
308 DECREF(result);
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000309 err_errno(CdError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000310 return NULL;
311 }
312 if (n < numframes)
313 if (resizestring(&result, n * sizeof(CDFRAME)))
314 return NULL;
315
316 return result;
317}
318
319static object *
320CD_seek(self, args)
321 cdplayerobject *self;
322 object *args;
323{
324 int min, sec, frame;
325 long block;
326
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000327 if (!newgetargs(args, "iii", &min, &sec, &frame))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000328 return NULL;
329
330 block = CDseek(self->ob_cdplayer, min, sec, frame);
331 if (block == -1) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000332 err_errno(CdError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000333 return NULL;
334 }
335
336 return newintobject(block);
337}
338
339static object *
340CD_seektrack(self, args)
341 cdplayerobject *self;
342 object *args;
343{
344 int track;
345 long block;
346
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000347 if (!newgetargs(args, "i", &track))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000348 return NULL;
349
350 block = CDseektrack(self->ob_cdplayer, track);
351 if (block == -1) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000352 err_errno(CdError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000353 return NULL;
354 }
355
356 return newintobject(block);
357}
358
359static object *
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000360CD_seekblock(self, args)
361 cdplayerobject *self;
362 object *args;
363{
364 unsigned long block;
365
366 if (!newgetargs(args, "l", &block))
367 return NULL;
368
369 block = CDseekblock(self->ob_cdplayer, block);
370 if (block == (unsigned long) -1) {
371 err_errno(CdError);
372 return NULL;
373 }
374
375 return newintobject(block);
376}
377
378static object *
Guido van Rossum16b8f301992-04-13 18:22:53 +0000379CD_stop(self, args)
380 cdplayerobject *self;
381 object *args;
382{
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000383 CDSTATUS status;
384
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000385 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000386 return NULL;
387
388 if (!CDstop(self->ob_cdplayer)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000389 if (CDgetstatus(self->ob_cdplayer, &status) &&
390 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000391 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000392 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000393 err_setstr(CdError, "stop failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000394 return NULL;
395 }
396
397 INCREF(None);
398 return None;
399}
400
401static object *
402CD_togglepause(self, args)
403 cdplayerobject *self;
404 object *args;
405{
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000406 CDSTATUS status;
407
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000408 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000409 return NULL;
410
411 if (!CDtogglepause(self->ob_cdplayer)) {
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000412 if (CDgetstatus(self->ob_cdplayer, &status) &&
413 status.state == CD_NODISC)
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000414 err_setstr(CdError, "no disc in player");
Guido van Rossumc3c7ac81992-05-06 09:48:30 +0000415 else
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000416 err_setstr(CdError, "togglepause failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000417 return NULL;
418 }
419
420 INCREF(None);
421 return None;
422}
423
424static struct methodlist cdplayer_methods[] = {
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000425 {"allowremoval", (method)CD_allowremoval, 1},
426 {"bestreadsize", (method)CD_bestreadsize, 1},
427 {"close", (method)CD_close, 1},
428 {"eject", (method)CD_eject, 1},
429 {"getstatus", (method)CD_getstatus, 1},
430 {"gettrackinfo", (method)CD_gettrackinfo, 1},
431 {"msftoblock", (method)CD_msftoblock, 1},
432 {"play", (method)CD_play, 1},
433 {"playabs", (method)CD_playabs, 1},
434 {"playtrack", (method)CD_playtrack, 1},
435 {"playtrackabs", (method)CD_playtrackabs, 1},
436 {"preventremoval", (method)CD_preventremoval, 1},
437 {"readda", (method)CD_readda, 1},
438 {"seek", (method)CD_seek, 1},
439 {"seekblock", (method)CD_seekblock, 1},
440 {"seektrack", (method)CD_seektrack, 1},
441 {"stop", (method)CD_stop, 1},
442 {"togglepause", (method)CD_togglepause, 1},
Guido van Rossum16b8f301992-04-13 18:22:53 +0000443 {NULL, NULL} /* sentinel */
444};
445
446static void
447cdplayer_dealloc(self)
448 cdplayerobject *self;
449{
450 if (self->ob_cdplayer != NULL)
451 CDclose(self->ob_cdplayer);
452 DEL(self);
453}
454
455static object *
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000456cdplayer_getattr(self, name)
457 cdplayerobject *self;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000458 char *name;
459{
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000460 if (self->ob_cdplayer == NULL) {
461 err_setstr(RuntimeError, "no player active");
462 return NULL;
463 }
464 return findmethod(cdplayer_methods, (object *)self, name);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000465}
466
467typeobject CdPlayertype = {
468 OB_HEAD_INIT(&Typetype)
469 0, /*ob_size*/
470 "cdplayer", /*tp_name*/
471 sizeof(cdplayerobject), /*tp_size*/
472 0, /*tp_itemsize*/
473 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000474 (destructor)cdplayer_dealloc, /*tp_dealloc*/
Guido van Rossum16b8f301992-04-13 18:22:53 +0000475 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000476 (getattrfunc)cdplayer_getattr, /*tp_getattr*/
Guido van Rossum16b8f301992-04-13 18:22:53 +0000477 0, /*tp_setattr*/
478 0, /*tp_compare*/
479 0, /*tp_repr*/
480};
481
482static object *
483newcdplayerobject(cdp)
484 CDPLAYER *cdp;
485{
486 cdplayerobject *p;
487
488 p = NEWOBJ(cdplayerobject, &CdPlayertype);
489 if (p == NULL)
490 return NULL;
491 p->ob_cdplayer = cdp;
492 return (object *) p;
493}
494
495static object *
496CD_open(self, args)
497 object *self, *args;
498{
499 char *dev, *direction;
500 CDPLAYER *cdp;
501
502 /*
503 * Variable number of args.
504 * First defaults to "None", second defaults to "r".
505 */
506 dev = NULL;
507 direction = "r";
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000508 if (!newgetargs(args, "|zs", &dev, &direction))
509 return NULL;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000510
511 cdp = CDopen(dev, direction);
512 if (cdp == NULL) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000513 err_errno(CdError);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000514 return NULL;
515 }
516
517 return newcdplayerobject(cdp);
518}
519
520typedef struct {
521 OB_HEAD
522 CDPARSER *ob_cdparser;
523 struct {
524 object *ob_cdcallback;
525 object *ob_cdcallbackarg;
526 } ob_cdcallbacks[NCALLBACKS];
527} cdparserobject;
528
529static void
530CD_callback(arg, type, data)
531 void *arg;
532 CDDATATYPES type;
533 void *data;
534{
535 object *result, *args, *v;
536 char *p;
537 int i;
538 cdparserobject *self;
539
540 self = (cdparserobject *) arg;
541 args = newtupleobject(3);
542 if (args == NULL)
543 return;
544 INCREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
545 settupleitem(args, 0, self->ob_cdcallbacks[type].ob_cdcallbackarg);
546 settupleitem(args, 1, newintobject((long) type));
547 switch (type) {
548 case cd_audio:
549 v = newsizedstringobject(data, CDDA_DATASIZE);
550 break;
551 case cd_pnum:
552 case cd_index:
553 v = newintobject(((CDPROGNUM *) data)->value);
554 break;
555 case cd_ptime:
556 case cd_atime:
Guido van Rossumece6efe1992-04-15 15:56:11 +0000557#define ptr ((struct cdtimecode *) data)
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000558 v = mkvalue("(iii)",
559 ptr->mhi * 10 + ptr->mlo,
Guido van Rossumece6efe1992-04-15 15:56:11 +0000560 ptr->shi * 10 + ptr->slo,
561 ptr->fhi * 10 + ptr->flo);
562#undef ptr
Guido van Rossum16b8f301992-04-13 18:22:53 +0000563 break;
564 case cd_catalog:
565 v = newsizedstringobject(NULL, 13);
566 p = getstringvalue(v);
567 for (i = 0; i < 13; i++)
568 *p++ = ((char *) data)[i] + '0';
569 break;
570 case cd_ident:
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000571#define ptr ((struct cdident *) data)
Guido van Rossum16b8f301992-04-13 18:22:53 +0000572 v = newsizedstringobject(NULL, 12);
573 p = getstringvalue(v);
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000574 CDsbtoa(p, ptr->country, 2);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000575 p += 2;
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000576 CDsbtoa(p, ptr->owner, 3);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000577 p += 3;
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000578 *p++ = ptr->year[0] + '0';
579 *p++ = ptr->year[1] + '0';
580 *p++ = ptr->serial[0] + '0';
581 *p++ = ptr->serial[1] + '0';
582 *p++ = ptr->serial[2] + '0';
583 *p++ = ptr->serial[3] + '0';
584 *p++ = ptr->serial[4] + '0';
585#undef ptr
Guido van Rossum16b8f301992-04-13 18:22:53 +0000586 break;
587 case cd_control:
588 v = newintobject((long) *((unchar *) data));
589 break;
590 }
591 settupleitem(args, 2, v);
592 if (err_occurred()) {
593 DECREF(args);
594 return;
595 }
596
597 result = call_object(self->ob_cdcallbacks[type].ob_cdcallback, args);
598 DECREF(args);
599 XDECREF(result);
600}
601
602static object *
603CD_deleteparser(self, args)
604 cdparserobject *self;
605 object *args;
606{
607 int i;
608
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000609 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000610 return NULL;
611
612 CDdeleteparser(self->ob_cdparser);
613 self->ob_cdparser = NULL;
614
615 /* no sense in keeping the callbacks, so remove them */
616 for (i = 0; i < NCALLBACKS; i++) {
617 XDECREF(self->ob_cdcallbacks[i].ob_cdcallback);
618 self->ob_cdcallbacks[i].ob_cdcallback = NULL;
619 XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg);
620 self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
621 }
622
623 INCREF(None);
624 return None;
625}
626
627static object *
628CD_parseframe(self, args)
629 cdparserobject *self;
630 object *args;
631{
632 char *cdfp;
633 int length;
634 CDFRAME *p;
635
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000636 if (!newgetargs(args, "s#", &cdfp, &length))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000637 return NULL;
638
639 if (length % sizeof(CDFRAME) != 0) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000640 err_setstr(TypeError, "bad length");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000641 return NULL;
642 }
643
644 p = (CDFRAME *) cdfp;
645 while (length > 0) {
646 CDparseframe(self->ob_cdparser, p);
647 length -= sizeof(CDFRAME);
648 p++;
649 if (err_occurred())
650 return NULL;
651 }
652
653 INCREF(None);
654 return None;
655}
656
657static object *
658CD_removecallback(self, args)
659 cdparserobject *self;
660 object *args;
661{
662 int type;
663
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000664 if (!newgetargs(args, "i", &type))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000665 return NULL;
666
Guido van Rossumf16eda51992-08-03 19:06:59 +0000667 if (type < 0 || type >= NCALLBACKS) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000668 err_setstr(TypeError, "bad type");
Guido van Rossumf16eda51992-08-03 19:06:59 +0000669 return NULL;
670 }
671
Guido van Rossum16b8f301992-04-13 18:22:53 +0000672 CDremovecallback(self->ob_cdparser, (CDDATATYPES) type);
673
674 XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
675 self->ob_cdcallbacks[type].ob_cdcallback = NULL;
676
677 XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
678 self->ob_cdcallbacks[type].ob_cdcallbackarg = NULL;
679
680 INCREF(None);
681 return None;
682}
683
684static object *
685CD_resetparser(self, args)
686 cdparserobject *self;
687 object *args;
688{
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000689 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000690 return NULL;
691
692 CDresetparser(self->ob_cdparser);
693
694 INCREF(None);
695 return None;
696}
697
698static object *
Guido van Rossumf16eda51992-08-03 19:06:59 +0000699CD_addcallback(self, args)
Guido van Rossum16b8f301992-04-13 18:22:53 +0000700 cdparserobject *self;
701 object *args;
702{
703 int type;
Guido van Rossum234f9421993-06-17 12:35:49 +0000704 object *func, *funcarg;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000705
Guido van Rossum16b8f301992-04-13 18:22:53 +0000706 /* XXX - more work here */
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000707 if (!newgetargs(args, "iOO", &type, &func, &funcarg))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000708 return NULL;
709
710 if (type < 0 || type >= NCALLBACKS) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000711 err_setstr(TypeError, "argument out of range");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000712 return NULL;
713 }
714
Sjoerd Mullender7c4eb401992-09-25 11:15:58 +0000715#ifdef CDsetcallback
Guido van Rossumf16eda51992-08-03 19:06:59 +0000716 CDaddcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback, (void *) self);
717#else
Guido van Rossum16b8f301992-04-13 18:22:53 +0000718 CDsetcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback, (void *) self);
Guido van Rossumf16eda51992-08-03 19:06:59 +0000719#endif
Guido van Rossum16b8f301992-04-13 18:22:53 +0000720 XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
Guido van Rossum234f9421993-06-17 12:35:49 +0000721 INCREF(func);
722 self->ob_cdcallbacks[type].ob_cdcallback = func;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000723 XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
Guido van Rossum234f9421993-06-17 12:35:49 +0000724 INCREF(funcarg);
725 self->ob_cdcallbacks[type].ob_cdcallbackarg = funcarg;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000726
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000727/*
728 if (type == cd_audio) {
729 sigfpe_[_UNDERFL].repls = _ZERO;
730 handle_sigfpes(_ON, _EN_UNDERFL, NULL, _ABORT_ON_ERROR, NULL);
731 }
732*/
733
Guido van Rossum16b8f301992-04-13 18:22:53 +0000734 INCREF(None);
735 return None;
736}
737
738static struct methodlist cdparser_methods[] = {
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000739 {"addcallback", (method)CD_addcallback, 1},
740 {"deleteparser", (method)CD_deleteparser, 1},
741 {"parseframe", (method)CD_parseframe, 1},
742 {"removecallback", (method)CD_removecallback, 1},
743 {"resetparser", (method)CD_resetparser, 1},
744 {"setcallback", (method)CD_addcallback, 1}, /* backward compatibility */
Guido van Rossum16b8f301992-04-13 18:22:53 +0000745 {NULL, NULL} /* sentinel */
746};
747
748static void
749cdparser_dealloc(self)
750 cdparserobject *self;
751{
752 int i;
753
754 for (i = 0; i < NCALLBACKS; i++) {
755 XDECREF(self->ob_cdcallbacks[i].ob_cdcallback);
756 self->ob_cdcallbacks[i].ob_cdcallback = NULL;
757 XDECREF(self->ob_cdcallbacks[i].ob_cdcallbackarg);
758 self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
759 }
760 CDdeleteparser(self->ob_cdparser);
761 DEL(self);
762}
763
764static object *
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000765cdparser_getattr(self, name)
766 cdparserobject *self;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000767 char *name;
768{
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000769 if (self->ob_cdparser == NULL) {
770 err_setstr(RuntimeError, "no parser active");
771 return NULL;
772 }
773
774 return findmethod(cdparser_methods, (object *)self, name);
Guido van Rossum16b8f301992-04-13 18:22:53 +0000775}
776
777typeobject CdParsertype = {
778 OB_HEAD_INIT(&Typetype)
779 0, /*ob_size*/
780 "cdparser", /*tp_name*/
781 sizeof(cdparserobject), /*tp_size*/
782 0, /*tp_itemsize*/
783 /* methods */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000784 (destructor)cdparser_dealloc, /*tp_dealloc*/
Guido van Rossum16b8f301992-04-13 18:22:53 +0000785 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000786 (getattrfunc)cdparser_getattr, /*tp_getattr*/
Guido van Rossum16b8f301992-04-13 18:22:53 +0000787 0, /*tp_setattr*/
788 0, /*tp_compare*/
789 0, /*tp_repr*/
790};
791
792static object *
793newcdparserobject(cdp)
794 CDPARSER *cdp;
795{
796 cdparserobject *p;
797 int i;
798
799 p = NEWOBJ(cdparserobject, &CdParsertype);
800 if (p == NULL)
801 return NULL;
802 p->ob_cdparser = cdp;
803 for (i = 0; i < NCALLBACKS; i++) {
804 p->ob_cdcallbacks[i].ob_cdcallback = NULL;
805 p->ob_cdcallbacks[i].ob_cdcallbackarg = NULL;
806 }
807 return (object *) p;
808}
809
810static object *
811CD_createparser(self, args)
812 object *self, *args;
813{
814 CDPARSER *cdp;
815
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000816 if (!newgetargs(args, ""))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000817 return NULL;
818 cdp = CDcreateparser();
819 if (cdp == NULL) {
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000820 err_setstr(CdError, "createparser failed");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000821 return NULL;
822 }
823
824 return newcdparserobject(cdp);
825}
826
827static object *
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000828CD_msftoframe(self, args)
829 object *self, *args;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000830{
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000831 int min, sec, frame;
Guido van Rossum16b8f301992-04-13 18:22:53 +0000832
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000833 if (!newgetargs(args, "iii", &min, &sec, &frame))
Guido van Rossum16b8f301992-04-13 18:22:53 +0000834 return NULL;
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000835
836 return newintobject((long) CDmsftoframe(min, sec, frame));
Guido van Rossum16b8f301992-04-13 18:22:53 +0000837}
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000838
Guido van Rossum16b8f301992-04-13 18:22:53 +0000839static struct methodlist CD_methods[] = {
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000840 {"open", (method)CD_open, 1},
841 {"createparser", (method)CD_createparser, 1},
842 {"msftoframe", (method)CD_msftoframe, 1},
Guido van Rossum16b8f301992-04-13 18:22:53 +0000843 {NULL, NULL} /* Sentinel */
844};
845
846void
847initcd()
848{
Sjoerd Mullender46927ba1992-09-24 10:48:40 +0000849 object *m, *d;
850
851 m = initmodule("cd", CD_methods);
852 d = getmoduledict(m);
853
854 CdError = newstringobject("cd.error");
Sjoerd Mullender542659b1995-03-28 12:06:23 +0000855 dictinsert(d, "error", CdError);
856
857 /* Identifiers for the different types of callbacks from the parser */
858 dictinsert(d, "audio", newintobject((long) cd_audio));
859 dictinsert(d, "pnum", newintobject((long) cd_pnum));
860 dictinsert(d, "index", newintobject((long) cd_index));
861 dictinsert(d, "ptime", newintobject((long) cd_ptime));
862 dictinsert(d, "atime", newintobject((long) cd_atime));
863 dictinsert(d, "catalog", newintobject((long) cd_catalog));
864 dictinsert(d, "ident", newintobject((long) cd_ident));
865 dictinsert(d, "control", newintobject((long) cd_control));
866
867 /* Block size information for digital audio data */
868 dictinsert(d, "DATASIZE", newintobject((long) CDDA_DATASIZE));
869 dictinsert(d, "BLOCKSIZE", newintobject((long) CDDA_BLOCKSIZE));
870
871 /* Possible states for the cd player */
872 dictinsert(d, "ERROR", newintobject((long) CD_ERROR));
873 dictinsert(d, "NODISC", newintobject((long) CD_NODISC));
874 dictinsert(d, "READY", newintobject((long) CD_READY));
875 dictinsert(d, "PLAYING", newintobject((long) CD_PLAYING));
876 dictinsert(d, "PAUSED", newintobject((long) CD_PAUSED));
877 dictinsert(d, "STILL", newintobject((long) CD_STILL));
878#ifdef CD_CDROM /* only newer versions of the library */
879 dictinsert(d, "CDROM", newintobject((long) CD_CDROM));
880#endif
881
882 if (err_occurred())
883 fatal("can't initialize module cd");
Guido van Rossum16b8f301992-04-13 18:22:53 +0000884}