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 } 136