From 84fb6f81169424782034293ab7b7ba3abe3391ba Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 21 Nov 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-11-21 --- alphapc/mmu.c | 2 +- alphapc/mouse.c | 163 +++++++++++++++++++++++++++++++++----------- alphapc/trap.c | 4 +- bitsy/devpenmouse.c | 44 ++++++++---- bitsy/devuda1341.c | 43 ++++++------ boot/bootauth.c | 3 +- mtx/trap.c | 40 +++++++---- pc/mouse.c | 50 ++++++++++---- port/devaudio.c | 34 ++++----- 9 files changed, 261 insertions(+), 122 deletions(-) diff --git a/alphapc/mmu.c b/alphapc/mmu.c index 88ba1809f0e18789f5ccbd3c2254275559622b41..005c2b142083dd3278cbad7d53372057f2a194eb 100644 --- a/alphapc/mmu.c +++ b/alphapc/mmu.c @@ -251,7 +251,7 @@ mmudump(void) if(up) { top = up->mmutop; if(top != nil) - iprint("top %lux top[N-1] %lux\n", top->va, ((uvlong *)top->va)[PTE2PG-1]); + iprint("top %lux top[N-1] %llux\n", top->va, ((uvlong *)top->va)[PTE2PG-1]); lvl2 = up->mmulvl2; if(lvl2 != nil) iprint("lvl2 %lux\n", lvl2->va); diff --git a/alphapc/mouse.c b/alphapc/mouse.c index d148d97cece8f7e24411982db1e1578d57afa095..701855dee72625c64cacf676fd3d16f408f938d1 100644 --- a/alphapc/mouse.c +++ b/alphapc/mouse.c @@ -22,6 +22,34 @@ enum MousePS2= 2, }; static int mousetype; +static int intellimouse; +static int packetsize; +static int resolution; +static int accelerated; + +enum +{ + CMaccelerated, + CMintellimouse, + CMlinear, + CMps2, + CMps2intellimouse, + CMres, + CMreset, + CMserial, +}; + +static Cmdtab mousectlmsg[] = +{ + CMaccelerated, "accelerated", 0, + CMintellimouse, "intellimouse", 1, + CMlinear, "linear", 1, + CMps2, "ps2", 1, + CMps2intellimouse, "ps2intellimouse", 1, + CMres, "res", 0, + CMreset, "reset", 1, + CMserial, "serial", 0, +}; /* * setup a serial mouse @@ -58,24 +86,55 @@ serialmouse(int port, char *type, int setspeed) * byte 1 - DX * byte 2 - DY * - * shift & left button is the same as middle button + * shift & right button is the same as middle button + * + * Intellimouse and AccuPoint with extra buttons deliver + * byte 3 - 00 or 01 or FF according to extra button state. + * extra buttons are mapped in this code to buttons 4 and 5. + * AccuPoint generates repeated events for these buttons; +* it and Intellimouse generate 'down' events only, so + * user-level code is required to generate button 'up' events + * if they are needed by the application. + * Also on laptops with AccuPoint AND external mouse, the + * controller may deliver 3 or 4 bytes according to the type + * of the external mouse; code must adapt. + * + * On the NEC Versa series (and perhaps others?) we seem to + * lose a byte from the packet every once in a while, which + * means we lose where we are in the instruction stream. + * To resynchronize, if we get a byte more than two seconds + * after the previous byte, we assume it's the first in a packet. */ static void ps2mouseputc(int c, int shift) { - static short msg[3]; + static short msg[4]; static int nb; - static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 5, 2, 3, 6, 7 }; + static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 3, 2, 3, 6, 7 }; + static ulong lasttick; + ulong m; int buttons, dx, dy; + /* + * Resynchronize in stream with timing; see comment above. + */ + m = MACHP(0)->ticks; + if(TK2SEC(m - lasttick) > 2) + nb = 0; + lasttick = m; + /* * check byte 0 for consistency */ if(nb==0 && (c&0xc8)!=0x08) - return; + if(intellimouse && (c==0x00 || c==0x01 || c==0xFF)){ + /* last byte of 4-byte packet */ + packetsize = 4; + return; + } msg[nb] = c; - if(++nb == 3){ + if(++nb == packetsize){ nb = 0; if(msg[0] & 0x10) msg[1] |= 0xFF00; @@ -83,9 +142,25 @@ ps2mouseputc(int c, int shift) msg[2] |= 0xFF00; buttons = b[(msg[0]&7) | (shift ? 8 : 0)]; + if(intellimouse && packetsize==4){ + if((msg[3]&0xc8) == 0x08){ + /* first byte of 3-byte packet */ + packetsize = 3; + msg[0] = msg[3]; + nb = 1; + /* fall through to emit previous packet */ + }else{ + /* the AccuPoint on the Toshiba 34[48]0CT encodes extra buttons as 4 and 5 */ + /* they repeat and don't release, however, so user-level timing code is required */ + if(msg[3] == 0xFF) + buttons |= 1<<3; + if(msg[3] == 0x01) + buttons |= 1<<4; + } + } dx = msg[1]; dy = -msg[2]; - mousetrack(buttons, dx, dy, TK2MS(MACHP(0)->ticks)); + mousetrack(dx, dy, buttons, TK2MS(MACHP(0)->ticks)); } return; } @@ -105,12 +180,9 @@ ps2mouse(void) i8042auxcmd(0xF4); mousetype = MousePS2; + packetsize = 3; } -static int intellimouse; -static int resolution; -static int accelerated; - static void setaccelerated(int x) { @@ -155,6 +227,7 @@ static void setintellimouse(void) { intellimouse = 1; + packetsize = 4; switch(mousetype){ case MousePS2: i8042auxcmd(0xF3); /* set sample */ @@ -170,6 +243,7 @@ setintellimouse(void) static void resetmouse(void) { + packetsize = 3; switch(mousetype){ case MousePS2: i8042auxcmd(0xF6); @@ -182,35 +256,35 @@ resetmouse(void) } void -mousectl(char* field[], int n) +mousectl(Cmdbuf *cb) { - if(strncmp(field[0], "serial", 6) == 0){ - switch(n){ - case 1: - serialmouse(atoi(field[0]+6), 0, 1); - break; - case 2: - serialmouse(atoi(field[1]), 0, 0); - break; - case 3: - default: - serialmouse(atoi(field[1]), field[2], 0); - break; - } - } else if(strcmp(field[0], "ps2") == 0){ + Cmdtab *ct; + + ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg)); + switch(ct->index){ + case CMaccelerated: + setaccelerated(cb->nf == 1 ? 1 : atoi(cb->f[1])); + break; + case CMintellimouse: + setintellimouse(); + break; + case CMlinear: + setlinear(); + break; + case CMps2: ps2mouse(); - } else if(strcmp(field[0], "ps2intellimouse") == 0){ + break; + case CMps2intellimouse: ps2mouse(); setintellimouse(); - } else if(strcmp(field[0], "accelerated") == 0){ - setaccelerated(n == 1 ? 1 : atoi(field[1])); - } else if(strcmp(field[0], "linear") == 0){ - setlinear(); - } else if(strcmp(field[0], "res") == 0){ - if(n >= 2) - n = atoi(field[1]); - setres(n); - } else if(strcmp(field[0], "reset") == 0){ + break; + case CMres: + if(cb->nf >= 2) + setres(atoi(cb->f[1])); + else + setres(1); + break; + case CMreset: resetmouse(); if(accelerated) setaccelerated(accelerated); @@ -218,9 +292,20 @@ mousectl(char* field[], int n) setres(resolution); if(intellimouse) setintellimouse(); - } else if(strcmp(field[0], "intellimouse") == 0){ - setintellimouse(); + break; + case CMserial: + switch(cb->nf){ + case 1: + serialmouse(atoi(cb->f[0]+6), 0, 1); + break; + case 2: + serialmouse(atoi(cb->f[1]), 0, 0); + break; + case 3: + default: + serialmouse(atoi(cb->f[1]), cb->f[2], 0); + break; + } + break; } - else - error(Ebadctl); } diff --git a/alphapc/trap.c b/alphapc/trap.c index 5828f6c3464bedea20b02d4f722bb5b792400ec1..c9d3e9b87e856bf1875b39b0d9feab1384a0e173 100644 --- a/alphapc/trap.c +++ b/alphapc/trap.c @@ -196,11 +196,11 @@ mcheck(Ureg *ur, void *x) m = x; data = x; - iprint("panic: Machine Check @%lux: %s (%lux) len %d\n", + iprint("panic: Machine Check @%lux: %s (%lux) len %lud\n", m, smcheck(m->code), m->code, m->len); iprint("proc offset %lux sys offset %lux\n", m->procoff, m->sysoff); for (i = 0, col = 0; i < m->len/8; i++) { - iprint("%.3lux: %.16llux%s", 8*i, data[i], (col == 2) ? "\n" : " "); + iprint("%.3x: %.16llux%s", 8*i, data[i], (col == 2) ? "\n" : " "); if (col++ == 2) col = 0; } diff --git a/bitsy/devpenmouse.c b/bitsy/devpenmouse.c index 3d2a738c8b30049334159f20f6c4d1b1ecbad9ca..366654a1e393ad77b56fa07a987d57be060a542d 100644 --- a/bitsy/devpenmouse.c +++ b/bitsy/devpenmouse.c @@ -83,6 +83,18 @@ static Dirtab mousedir[]={ "mousectl", {Qmousectl}, 0, 0660, }; +enum +{ + CMcalibrate, + CMswap, +}; + +static Cmdtab penmousecmd[] = +{ + CMcalibrate, "calibrate", 0, + CMswap, "swap", 1, +}; + static uchar buttonmap[8] = { 0, 1, 2, 3, 4, 5, 6, 7, }; @@ -325,6 +337,8 @@ penmousewrite(Chan *c, void *va, long n, vlong) { char *p; Point pt; + Cmdbuf *cb; + Cmdtab *ct; char buf[64], *field[5]; int nf, b; @@ -334,28 +348,27 @@ penmousewrite(Chan *c, void *va, long n, vlong) error(Eisdir); case Qmousectl: - if(n >= sizeof(buf)) - n = sizeof(buf)-1; - strncpy(buf, va, n); - if(buf[n - 1] == '\n') - buf[n-1] = 0; - else - buf[n] = 0; - nf = tokenize(buf, field, 5); - if(strcmp(field[0], "swap") == 0){ + cb = parsecmd(va, n); + if(waserror()){ + free(cb); + nexterror(); + } + ct = lookupcmd(cb, penmousecmd, nelem(penmousecmd)); + switch(ct->index){ + case CMswap: if(mouseswap) setbuttonmap("123"); else setbuttonmap("321"); mouseswap ^= 1; - } - else if(strcmp(field[0], "calibrate") == 0){ - if (nf == 1) { + break; + case CMcalibrate: + if (cb->nf == 1) { calibration.scalex = 1<<16; calibration.scaley = 1<<16; calibration.transx = 0; calibration.transy = 0; - } else if (nf == 5) { + } else if (cb->nf == 5) { if ((!isdigit(*field[1]) && *field[1] != '-') || (!isdigit(*field[2]) && *field[2] != '-') || (!isdigit(*field[3]) && *field[3] != '-') @@ -366,8 +379,11 @@ penmousewrite(Chan *c, void *va, long n, vlong) calibration.transx = strtol(field[3], nil, 0); calibration.transy = strtol(field[4], nil, 0); } else - print("calibrate %d fields\n", nf); + cmderror(cb, Ecmdargs); + break; } + free(cb); + poperror(); return n; case Qmousein: diff --git a/bitsy/devuda1341.c b/bitsy/devuda1341.c index fc88c7daf365f59bde20cb306790c0be28944f2e..f9d4ff07c9acc509af692af97c7385ef83aaaf6d 100644 --- a/bitsy/devuda1341.c +++ b/bitsy/devuda1341.c @@ -235,6 +235,7 @@ static struct [Vinvert] {"invert", Fin|Fout|Fmono, 0, 0, nil }, [Nvol] {0} }; + static void setreg(char *name, int val, int n); /* @@ -1247,10 +1248,10 @@ static long audiowrite(Chan *c, void *vp, long n, vlong) { long m, n0; - int i, nf, v, left, right, in, out; - char buf[255], *field[Ncmd]; + int i, v, left, right, in, out; char *p; IOstate *a; + Cmdbuf *cb; p = vp; n0 = n; @@ -1265,25 +1266,25 @@ audiowrite(Chan *c, void *vp, long n, vlong) right = 1; in = 1; out = 1; - if(n > sizeof(buf)-1) - n = sizeof(buf)-1; - memmove(buf, p, n); - buf[n] = '\0'; + cb = parsecmd(p, n); + if(waserror()){ + free(cb); + nexterror(); + } - nf = tokenize(buf, field, Ncmd); - for(i = 0; i < nf; i++){ + for(i = 0; i < cb->nf; i++){ /* * a number is volume */ - if(field[i][0] >= '0' && field[i][0] <= '9') { - m = strtoul(field[i], 0, 10); + if(cb->f[i][0] >= '0' && cb->f[i][0] <= '9') { + m = strtoul(cb->f[i], 0, 10); if (volumes[v].setval) volumes[v].setval(in, out, left, right, m); goto cont0; } for(m=0; volumes[m].name; m++) { - if(strcmp(field[i], volumes[m].name) == 0) { + if(strcmp(cb->f[i], volumes[m].name) == 0) { v = m; in = 1; out = 1; @@ -1293,38 +1294,38 @@ audiowrite(Chan *c, void *vp, long n, vlong) } } - if(strcmp(field[i], "reset") == 0) { + if(strcmp(cb->f[i], "reset") == 0) { resetlevel(); goto cont0; } - if(strcmp(field[i], "debug") == 0) { + if(strcmp(cb->f[i], "debug") == 0) { debug = debug?0:1; goto cont0; } - if(strcmp(field[i], "in") == 0) { + if(strcmp(cb->f[i], "in") == 0) { in = 1; out = 0; goto cont0; } - if(strcmp(field[i], "out") == 0) { + if(strcmp(cb->f[i], "out") == 0) { in = 0; out = 1; goto cont0; } - if(strcmp(field[i], "left") == 0) { + if(strcmp(cb->f[i], "left") == 0) { left = 1; right = 0; goto cont0; } - if(strcmp(field[i], "right") == 0) { + if(strcmp(cb->f[i], "right") == 0) { left = 0; right = 1; goto cont0; } - if(strcmp(field[i], "reg") == 0) { - if(nf < 3) + if(strcmp(cb->f[i], "reg") == 0) { + if(cb->nf < 3) error(Evolume); - setreg(field[1], atoi(field[2]), nf == 4 ? atoi(field[3]):1); + setreg(cb->f[1], atoi(cb->f[2]), cb->nf == 4 ? atoi(cb->f[3]):1); return n0; } error(Evolume); @@ -1332,6 +1333,8 @@ audiowrite(Chan *c, void *vp, long n, vlong) cont0:; } mxvolume(); + poperror(); + free(cb); break; case Qaudio: diff --git a/boot/bootauth.c b/boot/bootauth.c index 89d202589af3c62d9cdd4f8fce08a272245b0452..c27248a36a4bcaf9f7a18905e6c3a4f780b11bb2 100644 --- a/boot/bootauth.c +++ b/boot/bootauth.c @@ -21,9 +21,10 @@ authentication(int cpuflag) av[ac++] = "factotum"; //av[ac++] = "-d"; if(cpuflag) - av[ac++] = "-s"; + av[ac++] = "-S"; else av[ac++] = "-u"; + av[ac++] = "-sfactotum"; if(authaddr != nil){ av[ac++] = "-a"; av[ac++] = authaddr; diff --git a/mtx/trap.c b/mtx/trap.c index 02cbb377afd30198f1a04a3a95365b697821d05d..772a440feaf9771f0b88e83635e1a361c4d03457 100644 --- a/mtx/trap.c +++ b/mtx/trap.c @@ -152,13 +152,14 @@ trap(Ureg *ur) { int ecode; static struct {int callsched;} c = {1}; - int user = (ur->srr1 & MSR_PR) != 0; - char buf[ERRLEN]; + int user; + char buf[ERRMAX]; m->intrts = fastticks(nil); ecode = (ur->cause >> 8) & 0xff; +// user = (ur->srr1 & MSR_PR) != 0; -if(ur->status & MSR_RI == 0) +/* if(ur->status & MSR_RI == 0) print("double fault?: ecode = %d\n", ecode); switch(ecode){ case CEI: @@ -213,7 +214,7 @@ if(0) print("CDMISS: %lux %lux\n", m->epn, m->cmp1); delay(100); reset(); } - +*/ splhi(); if(user) notify(ur); @@ -223,8 +224,9 @@ void faultpower(Ureg *ureg, ulong addr, int read) { int user, insyscall, n; - char buf[ERRLEN]; - user = (ureg->srr1 & MSR_PR) != 0; + char buf[ERRMAX]; + +// user = (ureg->srr1 & MSR_PR) != 0; if(0)print("fault: pid=%ld pc = %lux, addr = %lux read = %d user = %d stack=%ulx\n", up->pid, ureg->pc, addr, read, user, &ureg); insyscall = up->insyscall; up->insyscall = 1; @@ -261,6 +263,7 @@ Lock veclock; void trapinit(void) { +#ifdef BLOG int i; IMM *io; @@ -289,11 +292,13 @@ trapinit(void) sethvec2(CIMISS<<8, itlbmiss); sethvec2(CDMISS<<8, dtlbmiss); sethvec2(CDTLBE<<8, dtlberror); +#endif } void intrenable(int v, void (*r)(Ureg*, void*), void *arg, int, char *name) { +#ifdef BLOG Handler *h; IMM *io; @@ -327,11 +332,13 @@ intrenable(int v, void (*r)(Ureg*, void*), void *arg, int, char *name) io->simask |= 1<<(31-LEV(v)); eieio(); iunlock(&veclock); +#endif } void intr(Ureg *ur) { +#ifdef BLOG int b, v; IMM *io; Handler *h; @@ -376,6 +383,7 @@ intr(Ureg *ur) if(v >= VectorCPIC) io->cisr |= 1<<(v-VectorCPIC); eieio(); +#endif } int @@ -457,7 +465,7 @@ dumpregs(Ureg *ur) ulong *l; if(up) { print("registers for %s %ld\n", up->text, up->pid); - if(ur->srr1 & MSR_PR == 0) +// if(ur->srr1 & MSR_PR == 0) if(ur->usp < (ulong)up->kstack || ur->usp > (ulong)up->kstack+KSTACK) print("invalid stack ptr\n"); } @@ -503,6 +511,7 @@ dumplongs(char*, ulong*, int) void reset(void) { +#ifdef BLOG IMM *io; io = m->iomem; @@ -515,6 +524,7 @@ print("reset = %ulx\n", getmsr()); // cause checkstop -> causes reset *(uchar*)(0xdeadbeef) = 0; *(ulong*)(0) = 0; +#endif } /* @@ -623,8 +633,8 @@ syscall(Ureg* ureg) long ret; int i, scallnr; - if((ureg->srr1 & MSR_PR) == 0) - panic("syscall: srr1 0x%4.4uX\n", ureg->srr1); +// if((ureg->srr1 & MSR_PR) == 0) +// panic("syscall: srr1 0x%4.4uX\n", ureg->srr1); m->syscall++; up->insyscall = 1; @@ -709,8 +719,8 @@ notify(Ureg* ur) n = &up->note[0]; if(strncmp(n->msg, "sys:", 4) == 0){ l = strlen(n->msg); - if(l > ERRLEN-15) /* " pc=0x12345678\0" */ - l = ERRLEN-15; + if(l > ERRMAX-15) /* " pc=0x12345678\0" */ + l = ERRMAX-15; sprint(n->msg+l, " pc=0x%.8lux", ur->pc); } @@ -735,7 +745,7 @@ notify(Ureg* ur) sp -= sizeof(Ureg); if(!okaddr((ulong)up->notify, BY2WD, 0) || - !okaddr(sp-ERRLEN-4*BY2WD, sizeof(Ureg)+ERRLEN+4*BY2WD, 1)) { + !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)) { pprint("suicide: bad address or sp in notify\n"); qunlock(&up->debug); pexit("Suicide", 0); @@ -744,8 +754,8 @@ notify(Ureg* ur) memmove((Ureg*)sp, ur, sizeof(Ureg)); *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */ up->ureg = (void*)sp; - sp -= BY2WD+ERRLEN; - memmove((char*)sp, up->note[0].msg, ERRLEN); + sp -= BY2WD+ERRMAX; + memmove((char*)sp, up->note[0].msg, ERRMAX); sp -= 3*BY2WD; *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD; /* arg 2 is string */ ur->r1 = (long)up->ureg; /* arg 1 is ureg* */ @@ -813,7 +823,7 @@ noted(Ureg* ureg, ulong arg0) pexit("Suicide", 0); } qunlock(&up->debug); - sp = oureg-4*BY2WD-ERRLEN; + sp = oureg-4*BY2WD-ERRMAX; splhi(); ureg->sp = sp; ((ulong*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */ diff --git a/pc/mouse.c b/pc/mouse.c index 701855dee72625c64cacf676fd3d16f408f938d1..bd36239a1ea0efa95b00f970840edebd77d6db08 100644 --- a/pc/mouse.c +++ b/pc/mouse.c @@ -26,10 +26,12 @@ static int intellimouse; static int packetsize; static int resolution; static int accelerated; +static int mousehwaccel; enum { CMaccelerated, + CMhwaccel, CMintellimouse, CMlinear, CMps2, @@ -42,6 +44,7 @@ enum static Cmdtab mousectlmsg[] = { CMaccelerated, "accelerated", 0, + CMhwaccel, "hwaccel", 2, CMintellimouse, "intellimouse", 1, CMlinear, "linear", 1, CMps2, "ps2", 1, @@ -181,34 +184,46 @@ ps2mouse(void) mousetype = MousePS2; packetsize = 3; + mousehwaccel = 1; } +/* + * The PS/2 Trackpoint multiplexor on the IBM Thinkpad T23 ignores + * acceleration commands. It is supposed to pass them on + * to the attached device, but my Logitech mouse is simply + * not behaving any differently. For such devices, we allow + * the user to use "hwaccel off" to tell us to back off to + * software acceleration even if we're using the PS/2 port. + * (Serial mice are always software accelerated.) + * For more information on the Thinkpad multiplexor, see + * http://wwwcssrv.almaden.ibm.com/trackpoint/ + */ static void setaccelerated(int x) { accelerated = x; - switch(mousetype){ - case MousePS2: - i8042auxcmd(0xE7); - break; - default: - mouseaccelerate(x); - break; + if(mousehwaccel){ + switch(mousetype){ + case MousePS2: + i8042auxcmd(0xE7); + return; + } } + mouseaccelerate(x); } static void setlinear(void) { accelerated = 0; - switch(mousetype){ - case MousePS2: - i8042auxcmd(0xE6); - break; - default: - mouseaccelerate(0); - break; + if(mousehwaccel){ + switch(mousetype){ + case MousePS2: + i8042auxcmd(0xE6); + return; + } } + mouseaccelerate(0); } static void @@ -307,5 +322,12 @@ mousectl(Cmdbuf *cb) break; } break; + case CMhwaccel: + if(strcmp(cb->f[1], "on")==0) + mousehwaccel = 1; + else if(strcmp(cb->f[1], "off")==0) + mousehwaccel = 0; + else + cmderror(cb, "bad mouse control message"); } } diff --git a/port/devaudio.c b/port/devaudio.c index e5ed7ebe8e1017074e6052741dbfd1e48f386d75..5c74856e2b1b981bacb4ae2c9276b829b99292d0 100644 --- a/port/devaudio.c +++ b/port/devaudio.c @@ -1067,8 +1067,8 @@ static long audiowrite(Chan *c, void *vp, long n, vlong) { long m, n0; - int i, nf, v, left, right, in, out; - char buf[255], *field[Ncmd]; + int i, v, left, right, in, out; + Cmdbuf *cb; Buf *b; char *a; @@ -1085,18 +1085,18 @@ audiowrite(Chan *c, void *vp, long n, vlong) right = 1; in = 1; out = 1; - if(n > sizeof(buf)-1) - n = sizeof(buf)-1; - memmove(buf, a, n); - buf[n] = '\0'; + cb = parsecmd(vp, n); + if(waserror()){ + free(cb); + nexterror(); + } - nf = tokenize(buf, field, Ncmd); - for(i = 0; i < nf; i++){ + for(i = 0; i < cb->nf; i++){ /* * a number is volume */ - if(field[i][0] >= '0' && field[i][0] <= '9') { - m = strtoul(field[i], 0, 10); + if(cb->f[i][0] >= '0' && cb->f[i][0] <= '9') { + m = strtoul(cb->f[i], 0, 10); if(left && out) audio.lovol[v] = m; if(left && in) @@ -1110,7 +1110,7 @@ audiowrite(Chan *c, void *vp, long n, vlong) } for(m=0; volumes[m].name; m++) { - if(strcmp(field[i], volumes[m].name) == 0) { + if(strcmp(cb->f[i], volumes[m].name) == 0) { v = m; in = 1; out = 1; @@ -1120,27 +1120,27 @@ audiowrite(Chan *c, void *vp, long n, vlong) } } - if(strcmp(field[i], "reset") == 0) { + if(strcmp(cb->f[i], "reset") == 0) { resetlevel(); mxvolume(); goto cont0; } - if(strcmp(field[i], "in") == 0) { + if(strcmp(cb->f[i], "in") == 0) { in = 1; out = 0; goto cont0; } - if(strcmp(field[i], "out") == 0) { + if(strcmp(cb->f[i], "out") == 0) { in = 0; out = 1; goto cont0; } - if(strcmp(field[i], "left") == 0) { + if(strcmp(cb->f[i], "left") == 0) { left = 1; right = 0; goto cont0; } - if(strcmp(field[i], "right") == 0) { + if(strcmp(cb->f[i], "right") == 0) { left = 0; right = 1; goto cont0; @@ -1149,6 +1149,8 @@ audiowrite(Chan *c, void *vp, long n, vlong) break; cont0:; } + free(cb); + poperror(); break; case Qaudio: