main.c 2.4 KB

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