19a747e4fSDavid du Colombier #include "acd.h"
29a747e4fSDavid du Colombier
39a747e4fSDavid du Colombier static int
iscmd(char * s,char * cmd)49a747e4fSDavid du Colombier iscmd(char *s, char *cmd)
59a747e4fSDavid du Colombier {
69a747e4fSDavid du Colombier int len;
79a747e4fSDavid du Colombier
89a747e4fSDavid du Colombier len = strlen(cmd);
99a747e4fSDavid du Colombier return strncmp(s, cmd, len)==0 && (s[len]=='\0' || s[len]==' ' || s[len]=='\t' || s[len]=='\n');
109a747e4fSDavid du Colombier }
119a747e4fSDavid du Colombier
129a747e4fSDavid du Colombier static char*
skip(char * s,char * cmd)139a747e4fSDavid du Colombier skip(char *s, char *cmd)
149a747e4fSDavid du Colombier {
159a747e4fSDavid du Colombier s += strlen(cmd);
169a747e4fSDavid du Colombier while(*s==' ' || *s=='\t' || *s=='\n')
179a747e4fSDavid du Colombier s++;
189a747e4fSDavid du Colombier return s;
199a747e4fSDavid du Colombier }
209a747e4fSDavid du Colombier
219a747e4fSDavid du Colombier //#define PLAYSTRING "/^[0-9:]+>"
229a747e4fSDavid du Colombier //#define PLAYSTRINGSPACE "/^[0-9:]+> ?"
239a747e4fSDavid du Colombier //#define INITSTRING "0:00> "
249a747e4fSDavid du Colombier
259a747e4fSDavid du Colombier #define INITSTRING "> "
269a747e4fSDavid du Colombier #define PLAYSTRING "/^>"
279a747e4fSDavid du Colombier #define PLAYSTRINGSPACE "/^> ?"
289a747e4fSDavid du Colombier
299a747e4fSDavid du Colombier /*
309a747e4fSDavid du Colombier * find the playing string, leave in addr
319a747e4fSDavid du Colombier * if q0, q1 are non-nil, set them to the addr of the string.
329a747e4fSDavid du Colombier */
339a747e4fSDavid du Colombier int
findplay(Window * w,char * s,ulong * q0,ulong * q1)349a747e4fSDavid du Colombier findplay(Window *w, char *s, ulong *q0, ulong *q1)
359a747e4fSDavid du Colombier {
369a747e4fSDavid du Colombier char xbuf[25];
379a747e4fSDavid du Colombier if(w->data < 0)
389a747e4fSDavid du Colombier w->data = winopenfile(w, "data");
399a747e4fSDavid du Colombier
409a747e4fSDavid du Colombier if(!winsetaddr(w, "#0", 1) || !winsetaddr(w, s, 1))
419a747e4fSDavid du Colombier return 0;
429a747e4fSDavid du Colombier
439a747e4fSDavid du Colombier seek(w->addr, 0, 0);
449a747e4fSDavid du Colombier if(read(w->addr, xbuf, 24) != 24)
459a747e4fSDavid du Colombier return 0;
469a747e4fSDavid du Colombier
479a747e4fSDavid du Colombier xbuf[24] = 0;
489a747e4fSDavid du Colombier if(q0)
499a747e4fSDavid du Colombier *q0 = atoi(xbuf);
509a747e4fSDavid du Colombier if(q1)
519a747e4fSDavid du Colombier *q1 = atoi(xbuf+12);
529a747e4fSDavid du Colombier
539a747e4fSDavid du Colombier return 1;
549a747e4fSDavid du Colombier }
559a747e4fSDavid du Colombier
569a747e4fSDavid du Colombier /*
579a747e4fSDavid du Colombier * find the playing string and replace the time
589a747e4fSDavid du Colombier */
599a747e4fSDavid du Colombier int
setplaytime(Window * w,char * new)609a747e4fSDavid du Colombier setplaytime(Window *w, char *new)
619a747e4fSDavid du Colombier {
629a747e4fSDavid du Colombier char buf[40];
639a747e4fSDavid du Colombier ulong q0, q1;
649a747e4fSDavid du Colombier
659a747e4fSDavid du Colombier return 1;
669a747e4fSDavid du Colombier if(!findplay(w, PLAYSTRING, &q0, &q1))
679a747e4fSDavid du Colombier return 0;
689a747e4fSDavid du Colombier
699a747e4fSDavid du Colombier q1--; /* > */
709a747e4fSDavid du Colombier sprint(buf, "#%lud,#%lud", q0, q1);
719a747e4fSDavid du Colombier DPRINT(2, "setaddr %s\n", buf);
729a747e4fSDavid du Colombier if(!winsetaddr(w, buf, 1))
739a747e4fSDavid du Colombier return 0;
749a747e4fSDavid du Colombier
759a747e4fSDavid du Colombier if(write(w->data, new, strlen(new)) != strlen(new))
769a747e4fSDavid du Colombier return 0;
779a747e4fSDavid du Colombier
789a747e4fSDavid du Colombier return 1;
799a747e4fSDavid du Colombier }
809a747e4fSDavid du Colombier
819a747e4fSDavid du Colombier /*
829a747e4fSDavid du Colombier * find the playing string, and remove it.
839a747e4fSDavid du Colombier * return the string at the beginning of hte next line in buf
849a747e4fSDavid du Colombier * (presumably a track number).
859a747e4fSDavid du Colombier */
869a747e4fSDavid du Colombier static int
unmarkplay(Window * w,char * buf,int n,ulong * q0,ulong * q1,ulong * qbegin)879a747e4fSDavid du Colombier unmarkplay(Window *w, char *buf, int n, ulong *q0, ulong *q1, ulong *qbegin)
889a747e4fSDavid du Colombier {
899a747e4fSDavid du Colombier char xbuf[24];
909a747e4fSDavid du Colombier
919a747e4fSDavid du Colombier if(!findplay(w, PLAYSTRINGSPACE, q0, q1))
929a747e4fSDavid du Colombier return 0;
939a747e4fSDavid du Colombier
949a747e4fSDavid du Colombier if(write(w->data, "", 0) < 0 || !winsetaddr(w, "+1+#0", 1))
959a747e4fSDavid du Colombier return 0;
969a747e4fSDavid du Colombier
979a747e4fSDavid du Colombier if(qbegin) {
989a747e4fSDavid du Colombier seek(w->addr, 0, 0);
999a747e4fSDavid du Colombier if(read(w->addr, xbuf, 24) != 24)
1009a747e4fSDavid du Colombier return 0;
1019a747e4fSDavid du Colombier *qbegin = atoi(xbuf);
1029a747e4fSDavid du Colombier }
1039a747e4fSDavid du Colombier
1049a747e4fSDavid du Colombier if(buf) {
1059a747e4fSDavid du Colombier if((n = read(w->data, buf, n-1)) < 0)
1069a747e4fSDavid du Colombier return 0;
1079a747e4fSDavid du Colombier
1089a747e4fSDavid du Colombier buf[n] = '\0';
1099a747e4fSDavid du Colombier }
1109a747e4fSDavid du Colombier
1119a747e4fSDavid du Colombier return 1;
1129a747e4fSDavid du Colombier }
1139a747e4fSDavid du Colombier
1149a747e4fSDavid du Colombier int
markplay(Window * w,ulong q0)1159a747e4fSDavid du Colombier markplay(Window *w, ulong q0)
1169a747e4fSDavid du Colombier {
1179a747e4fSDavid du Colombier char buf[20];
1189a747e4fSDavid du Colombier
1199a747e4fSDavid du Colombier if(w->data < 0)
1209a747e4fSDavid du Colombier w->data = winopenfile(w, "data");
1219a747e4fSDavid du Colombier
1229a747e4fSDavid du Colombier sprint(buf, "#%lud", q0);
1239a747e4fSDavid du Colombier DPRINT(2, "addr %s\n", buf);
1249a747e4fSDavid du Colombier if(!winsetaddr(w, buf, 1) || !winsetaddr(w, "-0", 1))
1259a747e4fSDavid du Colombier return 0;
1269a747e4fSDavid du Colombier if(write(w->data, INITSTRING, strlen(INITSTRING)) != strlen(INITSTRING))
1279a747e4fSDavid du Colombier return 0;
1289a747e4fSDavid du Colombier return 1;
1299a747e4fSDavid du Colombier }
1309a747e4fSDavid du Colombier
1319a747e4fSDavid du Colombier /* return 1 if handled, 0 otherwise */
1329a747e4fSDavid du Colombier int
cdcommand(Window * w,Drive * d,char * s)1339a747e4fSDavid du Colombier cdcommand(Window *w, Drive *d, char *s)
1349a747e4fSDavid du Colombier {
1359a747e4fSDavid du Colombier s = skip(s, "");
1369a747e4fSDavid du Colombier
1379a747e4fSDavid du Colombier if(iscmd(s, "Del")){
1389a747e4fSDavid du Colombier if(windel(w, 0))
1399a747e4fSDavid du Colombier threadexitsall(nil);
1409a747e4fSDavid du Colombier return 1;
1419a747e4fSDavid du Colombier }
1429a747e4fSDavid du Colombier if(iscmd(s, "Stop")){
1439a747e4fSDavid du Colombier unmarkplay(w, nil, 0, nil, nil, nil);
1449a747e4fSDavid du Colombier stop(d);
1459a747e4fSDavid du Colombier return 1;
1469a747e4fSDavid du Colombier }
1479a747e4fSDavid du Colombier if(iscmd(s, "Eject")){
1489a747e4fSDavid du Colombier unmarkplay(w, nil, 0, nil, nil, nil);
1499a747e4fSDavid du Colombier eject(d);
1509a747e4fSDavid du Colombier return 1;
1519a747e4fSDavid du Colombier }
1529a747e4fSDavid du Colombier if(iscmd(s, "Ingest")){
1539a747e4fSDavid du Colombier unmarkplay(w, nil, 0, nil, nil, nil);
1549a747e4fSDavid du Colombier ingest(d);
1559a747e4fSDavid du Colombier return 1;
1569a747e4fSDavid du Colombier }
1579a747e4fSDavid du Colombier if(iscmd(s, "Pause")){
1589a747e4fSDavid du Colombier pause(d);
1599a747e4fSDavid du Colombier return 1;
1609a747e4fSDavid du Colombier }
1619a747e4fSDavid du Colombier if(iscmd(s, "Resume")){
1629a747e4fSDavid du Colombier resume(d);
1639a747e4fSDavid du Colombier return 1;
1649a747e4fSDavid du Colombier }
1659a747e4fSDavid du Colombier return 0;
1669a747e4fSDavid du Colombier }
1679a747e4fSDavid du Colombier
1689a747e4fSDavid du Colombier void
drawtoc(Window * w,Drive * d,Toc * t)1699a747e4fSDavid du Colombier drawtoc(Window *w, Drive *d, Toc *t)
1709a747e4fSDavid du Colombier {
1719a747e4fSDavid du Colombier int i, playing;
1729a747e4fSDavid du Colombier
1739a747e4fSDavid du Colombier if(w->data < 0)
1749a747e4fSDavid du Colombier w->data = winopenfile(w, "data");
1759a747e4fSDavid du Colombier if(!winsetaddr(w, ",", 1))
1769a747e4fSDavid du Colombier return;
1779a747e4fSDavid du Colombier
178*3ff48bf5SDavid du Colombier fprint(w->data, "Title\n\n");
1799a747e4fSDavid du Colombier playing = -1;
1809a747e4fSDavid du Colombier if(d->status.state == Splaying || d->status.state == Spaused)
1819a747e4fSDavid du Colombier playing = d->status.track-t->track0;
1829a747e4fSDavid du Colombier
1839a747e4fSDavid du Colombier for(i=0; i<t->ntrack; i++)
184*3ff48bf5SDavid du Colombier fprint(w->data, "%s%d/ Track %d\n", i==playing ? "> " : "", i+1, i+1);
185*3ff48bf5SDavid du Colombier fprint(w->data, "");
1869a747e4fSDavid du Colombier }
1879a747e4fSDavid du Colombier
1889a747e4fSDavid du Colombier void
redrawtoc(Window * w,Toc * t)1899a747e4fSDavid du Colombier redrawtoc(Window *w, Toc *t)
1909a747e4fSDavid du Colombier {
1919a747e4fSDavid du Colombier int i;
1929a747e4fSDavid du Colombier char old[50];
1939a747e4fSDavid du Colombier
1949a747e4fSDavid du Colombier if(w->data < 0)
1959a747e4fSDavid du Colombier w->data = winopenfile(w, "data");
1969a747e4fSDavid du Colombier if(t->title) {
1979a747e4fSDavid du Colombier if(winsetaddr(w, "/Title", 1))
1989a747e4fSDavid du Colombier write(w->data, t->title, strlen(t->title));
1999a747e4fSDavid du Colombier }
2009a747e4fSDavid du Colombier for(i=0; i<t->ntrack; i++) {
2019a747e4fSDavid du Colombier if(t->track[i].title) {
2029a747e4fSDavid du Colombier sprint(old, "/Track %d", i+1);
2039a747e4fSDavid du Colombier if(winsetaddr(w, old, 1))
2049a747e4fSDavid du Colombier write(w->data, t->track[i].title, strlen(t->track[i].title));
2059a747e4fSDavid du Colombier }
2069a747e4fSDavid du Colombier }
2079a747e4fSDavid du Colombier }
2089a747e4fSDavid du Colombier
2099a747e4fSDavid du Colombier void
advancetrack(Drive * d,Window * w)2109a747e4fSDavid du Colombier advancetrack(Drive *d, Window *w)
2119a747e4fSDavid du Colombier {
2129a747e4fSDavid du Colombier int n;
2139a747e4fSDavid du Colombier ulong q0, q1, qnext;
2149a747e4fSDavid du Colombier char buf[20];
2159a747e4fSDavid du Colombier
2169a747e4fSDavid du Colombier q0 = q1 = 0;
2179a747e4fSDavid du Colombier if(!unmarkplay(w, buf, sizeof(buf), &q0, &q1, &qnext)) {
2189a747e4fSDavid du Colombier DPRINT(2, "unmark: %r\n");
2199a747e4fSDavid du Colombier return;
2209a747e4fSDavid du Colombier }
2219a747e4fSDavid du Colombier
2229a747e4fSDavid du Colombier DPRINT(2, "buf: %s\n", buf);
2239a747e4fSDavid du Colombier if(strncmp(buf, "repeat", 6) == 0) {
2249a747e4fSDavid du Colombier if(!winsetaddr(w, "#0", 1) || !findplay(w, "/^[0-9]+\\/", &qnext, nil)) {
2259a747e4fSDavid du Colombier DPRINT(2, "set/find: %r\n");
2269a747e4fSDavid du Colombier return;
2279a747e4fSDavid du Colombier }
2289a747e4fSDavid du Colombier if(w->data < 0)
2299a747e4fSDavid du Colombier w->data = winopenfile(w, "data");
2309a747e4fSDavid du Colombier if((n = read(w->data, buf, sizeof(buf)-1)) <= 0) {
2319a747e4fSDavid du Colombier DPRINT(2, "read %d: %r\n", n);
2329a747e4fSDavid du Colombier return;
2339a747e4fSDavid du Colombier }
2349a747e4fSDavid du Colombier buf[n] = 0;
2359a747e4fSDavid du Colombier DPRINT(2, "buf: %s\n", buf);
2369a747e4fSDavid du Colombier }
2379a747e4fSDavid du Colombier
2389a747e4fSDavid du Colombier if((n = atoi(buf)) == 0)
2399a747e4fSDavid du Colombier return;
2409a747e4fSDavid du Colombier
2419a747e4fSDavid du Colombier if(!markplay(w, qnext))
2429a747e4fSDavid du Colombier DPRINT(2, "err: %r");
2439a747e4fSDavid du Colombier
2449a747e4fSDavid du Colombier playtrack(d, n-1, n-1);
2459a747e4fSDavid du Colombier }
2469a747e4fSDavid du Colombier
2479a747e4fSDavid du Colombier void
acmeevent(Drive * d,Window * w,Event * e)2489a747e4fSDavid du Colombier acmeevent(Drive *d, Window *w, Event *e)
2499a747e4fSDavid du Colombier {
2509a747e4fSDavid du Colombier Event *ea, *e2, *eq;
2519a747e4fSDavid du Colombier char *s, *t, *buf;
2529a747e4fSDavid du Colombier int n, na;
2539a747e4fSDavid du Colombier ulong q0, q1;
2549a747e4fSDavid du Colombier
2559a747e4fSDavid du Colombier switch(e->c1){ /* origin of action */
2569a747e4fSDavid du Colombier default:
2579a747e4fSDavid du Colombier Unknown:
258*3ff48bf5SDavid du Colombier fprint(2, "unknown message %c%c\n", e->c1, e->c2);
2599a747e4fSDavid du Colombier break;
2609a747e4fSDavid du Colombier
2619a747e4fSDavid du Colombier case 'E': /* write to body or tag; can't affect us */
2629a747e4fSDavid du Colombier break;
2639a747e4fSDavid du Colombier
2649a747e4fSDavid du Colombier case 'F': /* generated by our actions; ignore */
2659a747e4fSDavid du Colombier break;
2669a747e4fSDavid du Colombier
2679a747e4fSDavid du Colombier case 'K': /* type away; we don't care */
2689a747e4fSDavid du Colombier break;
2699a747e4fSDavid du Colombier
2709a747e4fSDavid du Colombier case 'M': /* mouse event */
2719a747e4fSDavid du Colombier switch(e->c2){ /* type of action */
2729a747e4fSDavid du Colombier case 'x': /* mouse: button 2 in tag */
2739a747e4fSDavid du Colombier case 'X': /* mouse: button 2 in body */
2749a747e4fSDavid du Colombier ea = nil;
2759a747e4fSDavid du Colombier // e2 = nil;
2769a747e4fSDavid du Colombier s = e->b;
2779a747e4fSDavid du Colombier if(e->flag & 2){ /* null string with non-null expansion */
2789a747e4fSDavid du Colombier e2 = recvp(w->cevent);
2799a747e4fSDavid du Colombier if(e->nb==0)
2809a747e4fSDavid du Colombier s = e2->b;
2819a747e4fSDavid du Colombier }
2829a747e4fSDavid du Colombier if(e->flag & 8){ /* chorded argument */
2839a747e4fSDavid du Colombier ea = recvp(w->cevent); /* argument */
2849a747e4fSDavid du Colombier na = ea->nb;
2859a747e4fSDavid du Colombier recvp(w->cevent); /* ignore origin */
2869a747e4fSDavid du Colombier }else
2879a747e4fSDavid du Colombier na = 0;
2889a747e4fSDavid du Colombier
2899a747e4fSDavid du Colombier /* append chorded arguments */
2909a747e4fSDavid du Colombier if(na){
2919a747e4fSDavid du Colombier t = emalloc(strlen(s)+1+na+1);
2929a747e4fSDavid du Colombier sprint(t, "%s %s", s, ea->b);
2939a747e4fSDavid du Colombier s = t;
2949a747e4fSDavid du Colombier }
2959a747e4fSDavid du Colombier /* if it's a known command, do it */
2969a747e4fSDavid du Colombier /* if it's a long message, it can't be for us anyway */
2979a747e4fSDavid du Colombier DPRINT(2, "exec: %s\n", s);
2989a747e4fSDavid du Colombier if(!cdcommand(w, d, s)) /* send it back */
2999a747e4fSDavid du Colombier winwriteevent(w, e);
3009a747e4fSDavid du Colombier if(na)
3019a747e4fSDavid du Colombier free(s);
3029a747e4fSDavid du Colombier break;
3039a747e4fSDavid du Colombier
3049a747e4fSDavid du Colombier case 'l': /* mouse: button 3 in tag */
3059a747e4fSDavid du Colombier case 'L': /* mouse: button 3 in body */
3069a747e4fSDavid du Colombier // buf = nil;
3079a747e4fSDavid du Colombier eq = e;
3089a747e4fSDavid du Colombier if(e->flag & 2){
3099a747e4fSDavid du Colombier e2 = recvp(w->cevent);
3109a747e4fSDavid du Colombier eq = e2;
3119a747e4fSDavid du Colombier }
3129a747e4fSDavid du Colombier s = eq->b;
3139a747e4fSDavid du Colombier if(eq->q1>eq->q0 && eq->nb==0){
3149a747e4fSDavid du Colombier buf = emalloc((eq->q1-eq->q0)*UTFmax+1);
3159a747e4fSDavid du Colombier winread(w, eq->q0, eq->q1, buf);
3169a747e4fSDavid du Colombier s = buf;
3179a747e4fSDavid du Colombier }
3189a747e4fSDavid du Colombier DPRINT(2, "load %s\n", s);
3199a747e4fSDavid du Colombier if((n = atoi(s)) != 0) {
3209a747e4fSDavid du Colombier DPRINT(2, "mark %d\n", n);
3219a747e4fSDavid du Colombier q0 = q1 = 0;
3229a747e4fSDavid du Colombier unmarkplay(w, nil, 0, &q0, &q1, nil);
3239a747e4fSDavid du Colombier
3249a747e4fSDavid du Colombier /* adjust eq->q* for deletion */
3259a747e4fSDavid du Colombier if(eq->q0 > q1) {
3269a747e4fSDavid du Colombier eq->q0 -= (q1-q0);
3279a747e4fSDavid du Colombier eq->q1 -= (q1-q0);
3289a747e4fSDavid du Colombier }
3299a747e4fSDavid du Colombier if(!markplay(w, eq->q0))
3309a747e4fSDavid du Colombier DPRINT(2, "err: %r\n");
3319a747e4fSDavid du Colombier
3329a747e4fSDavid du Colombier playtrack(d, n-1, n-1);
3339a747e4fSDavid du Colombier } else
3349a747e4fSDavid du Colombier winwriteevent(w, e);
3359a747e4fSDavid du Colombier break;
3369a747e4fSDavid du Colombier
3379a747e4fSDavid du Colombier case 'i': /* mouse: text inserted in tag */
3389a747e4fSDavid du Colombier case 'I': /* mouse: text inserted in body */
3399a747e4fSDavid du Colombier case 'd': /* mouse: text deleted from tag */
3409a747e4fSDavid du Colombier case 'D': /* mouse: text deleted from body */
3419a747e4fSDavid du Colombier break;
3429a747e4fSDavid du Colombier
3439a747e4fSDavid du Colombier default:
3449a747e4fSDavid du Colombier goto Unknown;
3459a747e4fSDavid du Colombier }
3469a747e4fSDavid du Colombier }
3479a747e4fSDavid du Colombier }
348