diff options
Diffstat (limited to 'acme/bin/source/acd/acme.c')
-rw-r--r-- | acme/bin/source/acd/acme.c | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/acme/bin/source/acd/acme.c b/acme/bin/source/acd/acme.c new file mode 100644 index 000000000..514bdbc6e --- /dev/null +++ b/acme/bin/source/acd/acme.c @@ -0,0 +1,347 @@ +#include "acd.h" + +static int +iscmd(char *s, char *cmd) +{ + int len; + + len = strlen(cmd); + return strncmp(s, cmd, len)==0 && (s[len]=='\0' || s[len]==' ' || s[len]=='\t' || s[len]=='\n'); +} + +static char* +skip(char *s, char *cmd) +{ + s += strlen(cmd); + while(*s==' ' || *s=='\t' || *s=='\n') + s++; + return s; +} + +//#define PLAYSTRING "/^[0-9:]+>" +//#define PLAYSTRINGSPACE "/^[0-9:]+> ?" +//#define INITSTRING "0:00> " + +#define INITSTRING "> " +#define PLAYSTRING "/^>" +#define PLAYSTRINGSPACE "/^> ?" + +/* + * find the playing string, leave in addr + * if q0, q1 are non-nil, set them to the addr of the string. + */ +int +findplay(Window *w, char *s, ulong *q0, ulong *q1) +{ + char xbuf[25]; + if(w->data < 0) + w->data = winopenfile(w, "data"); + + if(!winsetaddr(w, "#0", 1) || !winsetaddr(w, s, 1)) + return 0; + + seek(w->addr, 0, 0); + if(read(w->addr, xbuf, 24) != 24) + return 0; + + xbuf[24] = 0; + if(q0) + *q0 = atoi(xbuf); + if(q1) + *q1 = atoi(xbuf+12); + + return 1; +} + +/* + * find the playing string and replace the time + */ +int +setplaytime(Window *w, char *new) +{ + char buf[40]; + ulong q0, q1; + +return 1; + if(!findplay(w, PLAYSTRING, &q0, &q1)) + return 0; + + q1--; /* > */ + sprint(buf, "#%lud,#%lud", q0, q1); + DPRINT(2, "setaddr %s\n", buf); + if(!winsetaddr(w, buf, 1)) + return 0; + + if(write(w->data, new, strlen(new)) != strlen(new)) + return 0; + + return 1; +} + +/* + * find the playing string, and remove it. + * return the string at the beginning of hte next line in buf + * (presumably a track number). + */ +static int +unmarkplay(Window *w, char *buf, int n, ulong *q0, ulong *q1, ulong *qbegin) +{ + char xbuf[24]; + + if(!findplay(w, PLAYSTRINGSPACE, q0, q1)) + return 0; + + if(write(w->data, "", 0) < 0 || !winsetaddr(w, "+1+#0", 1)) + return 0; + + if(qbegin) { + seek(w->addr, 0, 0); + if(read(w->addr, xbuf, 24) != 24) + return 0; + *qbegin = atoi(xbuf); + } + + if(buf) { + if((n = read(w->data, buf, n-1)) < 0) + return 0; + + buf[n] = '\0'; + } + + return 1; +} + +int +markplay(Window *w, ulong q0) +{ + char buf[20]; + + if(w->data < 0) + w->data = winopenfile(w, "data"); + + sprint(buf, "#%lud", q0); + DPRINT(2, "addr %s\n", buf); + if(!winsetaddr(w, buf, 1) || !winsetaddr(w, "-0", 1)) + return 0; + if(write(w->data, INITSTRING, strlen(INITSTRING)) != strlen(INITSTRING)) + return 0; + return 1; +} + +/* return 1 if handled, 0 otherwise */ +int +cdcommand(Window *w, Drive *d, char *s) +{ + s = skip(s, ""); + + if(iscmd(s, "Del")){ + if(windel(w, 0)) + threadexitsall(nil); + return 1; + } + if(iscmd(s, "Stop")){ + unmarkplay(w, nil, 0, nil, nil, nil); + stop(d); + return 1; + } + if(iscmd(s, "Eject")){ + unmarkplay(w, nil, 0, nil, nil, nil); + eject(d); + return 1; + } + if(iscmd(s, "Ingest")){ + unmarkplay(w, nil, 0, nil, nil, nil); + ingest(d); + return 1; + } + if(iscmd(s, "Pause")){ + pause(d); + return 1; + } + if(iscmd(s, "Resume")){ + resume(d); + return 1; + } + return 0; +} + +void +drawtoc(Window *w, Drive *d, Toc *t) +{ + int i, playing; + + if(w->data < 0) + w->data = winopenfile(w, "data"); + if(!winsetaddr(w, ",", 1)) + return; + + fprint(w->data, "Title\n\n"); + playing = -1; + if(d->status.state == Splaying || d->status.state == Spaused) + playing = d->status.track-t->track0; + + for(i=0; i<t->ntrack; i++) + fprint(w->data, "%s%d/ Track %d\n", i==playing ? "> " : "", i+1, i+1); + fprint(w->data, ""); +} + +void +redrawtoc(Window *w, Toc *t) +{ + int i; + char old[50]; + + if(w->data < 0) + w->data = winopenfile(w, "data"); + if(t->title) { + if(winsetaddr(w, "/Title", 1)) + write(w->data, t->title, strlen(t->title)); + } + for(i=0; i<t->ntrack; i++) { + if(t->track[i].title) { + sprint(old, "/Track %d", i+1); + if(winsetaddr(w, old, 1)) + write(w->data, t->track[i].title, strlen(t->track[i].title)); + } + } +} + +void +advancetrack(Drive *d, Window *w) +{ + int n; + ulong q0, q1, qnext; + char buf[20]; + + q0 = q1 = 0; + if(!unmarkplay(w, buf, sizeof(buf), &q0, &q1, &qnext)) { + DPRINT(2, "unmark: %r\n"); + return; + } + + DPRINT(2, "buf: %s\n", buf); + if(strncmp(buf, "repeat", 6) == 0) { + if(!winsetaddr(w, "#0", 1) || !findplay(w, "/^[0-9]+\\/", &qnext, nil)) { + DPRINT(2, "set/find: %r\n"); + return; + } + if(w->data < 0) + w->data = winopenfile(w, "data"); + if((n = read(w->data, buf, sizeof(buf)-1)) <= 0) { + DPRINT(2, "read %d: %r\n", n); + return; + } + buf[n] = 0; + DPRINT(2, "buf: %s\n", buf); + } + + if((n = atoi(buf)) == 0) + return; + + if(!markplay(w, qnext)) + DPRINT(2, "err: %r"); + + playtrack(d, n-1, n-1); +} + +void +acmeevent(Drive *d, Window *w, Event *e) +{ + Event *ea, *e2, *eq; + char *s, *t, *buf; + int n, na; + ulong q0, q1; + + switch(e->c1){ /* origin of action */ + default: + Unknown: + fprint(2, "unknown message %c%c\n", e->c1, e->c2); + break; + + case 'E': /* write to body or tag; can't affect us */ + break; + + case 'F': /* generated by our actions; ignore */ + break; + + case 'K': /* type away; we don't care */ + break; + + case 'M': /* mouse event */ + switch(e->c2){ /* type of action */ + case 'x': /* mouse: button 2 in tag */ + case 'X': /* mouse: button 2 in body */ + ea = nil; + // e2 = nil; + s = e->b; + if(e->flag & 2){ /* null string with non-null expansion */ + e2 = recvp(w->cevent); + if(e->nb==0) + s = e2->b; + } + if(e->flag & 8){ /* chorded argument */ + ea = recvp(w->cevent); /* argument */ + na = ea->nb; + recvp(w->cevent); /* ignore origin */ + }else + na = 0; + + /* append chorded arguments */ + if(na){ + t = emalloc(strlen(s)+1+na+1); + sprint(t, "%s %s", s, ea->b); + s = t; + } + /* if it's a known command, do it */ + /* if it's a long message, it can't be for us anyway */ + DPRINT(2, "exec: %s\n", s); + if(!cdcommand(w, d, s)) /* send it back */ + winwriteevent(w, e); + if(na) + free(s); + break; + + case 'l': /* mouse: button 3 in tag */ + case 'L': /* mouse: button 3 in body */ + // buf = nil; + eq = e; + if(e->flag & 2){ + e2 = recvp(w->cevent); + eq = e2; + } + s = eq->b; + if(eq->q1>eq->q0 && eq->nb==0){ + buf = emalloc((eq->q1-eq->q0)*UTFmax+1); + winread(w, eq->q0, eq->q1, buf); + s = buf; + } + DPRINT(2, "load %s\n", s); + if((n = atoi(s)) != 0) { + DPRINT(2, "mark %d\n", n); + q0 = q1 = 0; + unmarkplay(w, nil, 0, &q0, &q1, nil); + + /* adjust eq->q* for deletion */ + if(eq->q0 > q1) { + eq->q0 -= (q1-q0); + eq->q1 -= (q1-q0); + } + if(!markplay(w, eq->q0)) + DPRINT(2, "err: %r\n"); + + playtrack(d, n-1, n-1); + } else + winwriteevent(w, e); + break; + + case 'i': /* mouse: text inserted in tag */ + case 'I': /* mouse: text inserted in body */ + case 'd': /* mouse: text deleted from tag */ + case 'D': /* mouse: text deleted from body */ + break; + + default: + goto Unknown; + } + } +} |