Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "acd.h"
2
 
3
int debug;
4
 
5
void
6
usage(void)
7
{
8
	fprint(2, "usage: acd dev\n");
9
	threadexitsall("usage");
10
}
11
 
12
Alt
13
mkalt(Channel *c, void *v, int op)
14
{
15
	Alt a;
16
 
17
	memset(&a, 0, sizeof(a));
18
	a.c = c;
19
	a.v = v;
20
	a.op = op;
21
	return a;
22
}
23
 
24
void
25
freetoc(Toc *t)
26
{
27
	int i;
28
 
29
	free(t->title);
30
	for(i=0; i<t->ntrack; i++)
31
		free(t->track[i].title);
32
}
33
 
34
void
35
eventwatcher(Drive *d)
36
{
37
	enum { STATUS, WEVENT, TOCDISP, DBREQ, DBREPLY, NALT };
38
	Alt alts[NALT+1];
39
	Toc nt, tdb;
40
	Event *e;
41
	Window *w;
42
	Cdstatus s;
43
	char buf[40];
44
 
45
	w = d->w;
46
 
47
	alts[STATUS] = mkalt(d->cstatus, &s, CHANRCV);
48
	alts[WEVENT] = mkalt(w->cevent, &e, CHANRCV);
49
	alts[TOCDISP] = mkalt(d->ctocdisp, &nt, CHANRCV);
50
	alts[DBREQ] = mkalt(d->cdbreq, &tdb, CHANNOP);
51
	alts[DBREPLY] = mkalt(d->cdbreply, &nt, CHANRCV);
52
	alts[NALT] = mkalt(nil, nil, CHANEND);
53
	for(;;) {
54
		switch(alt(alts)) {
55
		case STATUS:
56
			//DPRINT(2, "s...");
57
			d->status = s;
58
			if(s.state == Scompleted) {
59
				s.state = Sunknown;
60
				advancetrack(d, w);
61
			}
62
			//DPRINT(2, "status %d %d %d %M %M\n", s.state, s.track, s.index, s.abs, s.rel);
63
			sprint(buf, "%d:%2.2d", s.rel.m, s.rel.s);
64
			setplaytime(w, buf);
65
			break;
66
		case WEVENT:
67
			//DPRINT(2, "w...");
68
			acmeevent(d, w, e);
69
			break;
70
		case TOCDISP:
71
			//DPRINT(2,"td...");
72
			freetoc(&d->toc);
73
			d->toc = nt;
74
			drawtoc(w, d, &d->toc);
75
			tdb = nt;
76
			alts[DBREQ].op = CHANSND;
77
			break;
78
		case DBREQ:	/* sent */
79
			//DPRINT(2,"dreq...");
80
			alts[DBREQ].op = CHANNOP;
81
			break;
82
		case DBREPLY:
83
			//DPRINT(2,"drep...");
84
			freetoc(&d->toc);
85
			d->toc = nt;
86
			redrawtoc(w, &d->toc);
87
			break;
88
		}
89
	}
90
}
91
 
92
void
93
threadmain(int argc, char **argv)
94
{
95
	Scsi *s;
96
	Drive *d;
97
	char buf[80];
98
 
99
	ARGBEGIN{
100
	case 'v':
101
		debug++;
102
		scsiverbose++;
103
	}ARGEND
104
 
105
	if(argc != 1)
106
		usage();
107
 
108
	fmtinstall('M', msfconv);
109
 
110
	if((s = openscsi(argv[0])) == nil)
111
		error("opening scsi: %r");
112
 
113
	d = malloc(sizeof(*d));
114
	if(d == nil)
115
		error("out of memory");
116
	memset(d, 0, sizeof d);
117
 
118
	d->scsi = s;
119
	d->w = newwindow();
120
	d->ctocdisp = chancreate(sizeof(Toc), 0);
121
	d->cdbreq = chancreate(sizeof(Toc), 0);
122
	d->cdbreply = chancreate(sizeof(Toc), 0);
123
	d->cstatus = chancreate(sizeof(Cdstatus), 0);
124
 
125
	proccreate(wineventproc, d->w, STACK);
126
	proccreate(cddbproc, d, STACK);
127
	proccreate(cdstatusproc, d, STACK);
128
 
129
	cleanname(argv[0]);
130
	snprint(buf, sizeof(buf), "%s/", argv[0]);
131
	winname(d->w, buf);
132
 
133
	wintagwrite(d->w, "Stop Pause Resume Eject Ingest ", 5+6+7+6+7);
134
	eventwatcher(d);
135
}