summaryrefslogtreecommitdiff
path: root/acme/bin/source/acd/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'acme/bin/source/acd/main.c')
-rw-r--r--acme/bin/source/acd/main.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/acme/bin/source/acd/main.c b/acme/bin/source/acd/main.c
new file mode 100644
index 000000000..2ac388f56
--- /dev/null
+++ b/acme/bin/source/acd/main.c
@@ -0,0 +1,135 @@
+#include "acd.h"
+
+int debug;
+
+void
+usage(void)
+{
+ fprint(2, "usage: acd dev\n");
+ threadexitsall("usage");
+}
+
+Alt
+mkalt(Channel *c, void *v, int op)
+{
+ Alt a;
+
+ memset(&a, 0, sizeof(a));
+ a.c = c;
+ a.v = v;
+ a.op = op;
+ return a;
+}
+
+void
+freetoc(Toc *t)
+{
+ int i;
+
+ free(t->title);
+ for(i=0; i<t->ntrack; i++)
+ free(t->track[i].title);
+}
+
+void
+eventwatcher(Drive *d)
+{
+ enum { STATUS, WEVENT, TOCDISP, DBREQ, DBREPLY, NALT };
+ Alt alts[NALT+1];
+ Toc nt, tdb;
+ Event *e;
+ Window *w;
+ Cdstatus s;
+ char buf[40];
+
+ w = d->w;
+
+ alts[STATUS] = mkalt(d->cstatus, &s, CHANRCV);
+ alts[WEVENT] = mkalt(w->cevent, &e, CHANRCV);
+ alts[TOCDISP] = mkalt(d->ctocdisp, &nt, CHANRCV);
+ alts[DBREQ] = mkalt(d->cdbreq, &tdb, CHANNOP);
+ alts[DBREPLY] = mkalt(d->cdbreply, &nt, CHANRCV);
+ alts[NALT] = mkalt(nil, nil, CHANEND);
+ for(;;) {
+ switch(alt(alts)) {
+ case STATUS:
+ //DPRINT(2, "s...");
+ d->status = s;
+ if(s.state == Scompleted) {
+ s.state = Sunknown;
+ advancetrack(d, w);
+ }
+ //DPRINT(2, "status %d %d %d %M %M\n", s.state, s.track, s.index, s.abs, s.rel);
+ sprint(buf, "%d:%2.2d", s.rel.m, s.rel.s);
+ setplaytime(w, buf);
+ break;
+ case WEVENT:
+ //DPRINT(2, "w...");
+ acmeevent(d, w, e);
+ break;
+ case TOCDISP:
+ //DPRINT(2,"td...");
+ freetoc(&d->toc);
+ d->toc = nt;
+ drawtoc(w, d, &d->toc);
+ tdb = nt;
+ alts[DBREQ].op = CHANSND;
+ break;
+ case DBREQ: /* sent */
+ //DPRINT(2,"dreq...");
+ alts[DBREQ].op = CHANNOP;
+ break;
+ case DBREPLY:
+ //DPRINT(2,"drep...");
+ freetoc(&d->toc);
+ d->toc = nt;
+ redrawtoc(w, &d->toc);
+ break;
+ }
+ }
+}
+
+void
+threadmain(int argc, char **argv)
+{
+ Scsi *s;
+ Drive *d;
+ char buf[80];
+
+ ARGBEGIN{
+ case 'v':
+ debug++;
+ scsiverbose++;
+ }ARGEND
+
+ if(argc != 1)
+ usage();
+
+ fmtinstall('M', msfconv);
+
+ if((s = openscsi(argv[0])) == nil)
+ error("opening scsi: %r");
+
+ d = malloc(sizeof(*d));
+ if(d == nil)
+ error("out of memory");
+ memset(d, 0, sizeof d);
+
+ d->scsi = s;
+ d->w = newwindow();
+ d->ctocdisp = chancreate(sizeof(Toc), 0);
+ d->cdbreq = chancreate(sizeof(Toc), 0);
+ d->cdbreply = chancreate(sizeof(Toc), 0);
+ d->cstatus = chancreate(sizeof(Cdstatus), 0);
+
+ proccreate(wineventproc, d->w, STACK);
+ proccreate(cddbproc, d, STACK);
+ proccreate(cdstatusproc, d, STACK);
+
+ cleanname(argv[0]);
+ snprint(buf, sizeof(buf), "%s/", argv[0]);
+ winname(d->w, buf);
+
+ wintagwrite(d->w, "Stop Pause Resume Eject Ingest ", 5+6+7+6+7);
+ eventwatcher(d);
+}