From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from duke.felloff.net ([216.126.196.34]) by ur; Fri Sep 30 03:40:20 EDT 2016 Message-ID: Date: Fri, 30 Sep 2016 09:40:14 +0200 From: cinap_lenrek@felloff.net To: 9front@9front.org Subject: Re: [9front] Middle button on usb mice In-Reply-To: <3ed47344565c98254ffefc876b353e28@felloff.net> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="upas-mmthvbquyvqirlpueixzrgitby" List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: JSON over ORM proxy-oriented wrapper information-aware generator This is a multi-part message in MIME format. --upas-mmthvbquyvqirlpueixzrgitby Content-Disposition: inline Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit screwed up attachment.. -- cinap --upas-mmthvbquyvqirlpueixzrgitby Content-Disposition: attachment; filename=a.c Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit #include #include #include #include "usb.h" #include "hid.h" typedef struct Hidreport Hidreport; struct Hidreport { int x; int y; int z; int b; int m; int absx; int absy; int absz; int nk; uchar k[64]; int o; uchar *e; uchar p[128]; }; static int debug = 3; static int signext(int v, int bits) { int s; s = sizeof(v)*8 - bits; v <<= s; v >>= s; return v; } static int getbits(uchar *p, uchar *e, int bits, int off) { int v, m; p += off/8; off %= 8; v = 0; m = 1; if(p < e){ while(bits--){ if(*p & (1<= e) break; off = 0; } m <<= 1; } } return v; } enum { Ng = RepCnt+1, UsgCnt = Delim+1, /* fake */ Nl = UsgCnt+1, Nu = 256, }; static uchar* repparse1(uchar *d, uchar *e, int g[], int l[], int c, void (*f)(int t, int v, int g[], int l[], int c, void *a), void *a) { int z, k, t, v, i; while(d < e){ v = 0; t = *d++; z = t & 3, t >>= 2; k = t & 3, t >>= 2; switch(z){ case 3: d += 4; if(d > e) continue; v = d[-4] | d[-3]<<8 | d[-2]<<16 | d[-1]<<24; break; case 2: d += 2; if(d > e) continue; v = d[-2] | d[-1]<<8; break; case 1: d++; if(d > e) continue; v = d[-1]; break; } switch(k){ case 0: /* main item*/ switch(t){ case Collection: memset(l, 0, Nl*sizeof(l[0])); d = repparse1(d, e, g, l, v, f, a); continue; case CollectionEnd: return d; case Input: case Output: case Feature: if(l[UsgCnt] == 0 && l[UsagMin] != 0 && l[UsagMin] < l[UsagMax]) for(i=l[UsagMin]; i<=l[UsagMax] && l[UsgCnt] < Nu; i++) l[Nl + l[UsgCnt]++] = i; for(i=0; ip[0] != g[RepId]){ p->o = 0; return; } if(p->o < 8) p->o = 8; /* skip report id byte */ } v = getbits(p->p, p->e, g[RepSize], p->o); p->o += g[RepSize]; if((f & (Fconst|Fdata)) != Fdata) return; if(debug > 1) fprint(2, "hidparse: t=%x f=%x usage=%x v=%x\n", t, f, l[Usage], v); if((l[Usage]>>16) == 0x07){ /* keycode */ if((f & (Fvar|Farray)) == Fvar) if(v != 0) v = l[Usage] & 0xFF; if(p->nk < nelem(p->k) && v != 0) p->k[p->nk++] = v; return; } if(g[LogiMin] < 0) v = signext(v, g[RepSize]); if((f & (Fvar|Farray)) == Fvar && v >= g[LogiMin] && v <= g[LogiMax]){ /* * we use logical units below, but need the * sign to be correct for mouse deltas. * so if physical unit is signed but logical * is unsigned, convert to signed but in logical * units. */ if((f & (Fabs|Frel)) == Frel && g[PhysMin] < 0 && g[PhysMax] > 0 && g[LogiMin] >= 0 && g[LogiMin] < g[LogiMax]) v -= (g[PhysMax] * (g[LogiMax] - g[LogiMin])) / (g[PhysMax] - g[PhysMin]); switch(l[Usage]){ case 0x090001: case 0x090002: case 0x090003: case 0x090004: case 0x090005: case 0x090006: case 0x090007: case 0x090008: m = 1<<(l[Usage] - 0x090001); p->m |= m; p->b &= ~m; if(v != 0) p->b |= m; break; case 0x010030: if((f & (Fabs|Frel)) == Fabs){ p->x = (v - p->absx); p->absx = v; } else { p->x = v; p->absx += v; } break; case 0x010031: if((f & (Fabs|Frel)) == Fabs){ p->y = (v - p->absy); p->absy = v; } else { p->y = v; p->absy += v; } break; case 0x010038: if((f & (Fabs|Frel)) == Fabs){ p->z = (v - p->absz); p->absz = v; } else { p->z = v; p->absz += v; } break; } } } static void usage(void) { fprint(2, "usage: %s [-d] devid\n", argv0); threadexits("usage"); } static uchar rep[] ={ 0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03, 0x15, 0x00, 0x25, 0x01, 0x95, 0x08, 0x75, 0x01, 0x81, 0x02, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7f, 0x75, 0x08, 0x95, 0x03, 0x81, 0x06, 0xc0, 0xc0, }; void threadmain(int argc, char* argv[]) { Hidreport p = {0}; p.o = 0; p.e = p.p + 3; p.p[0] = 1<<2; repparse(rep, rep+sizeof(rep), hidparse, &p); } --upas-mmthvbquyvqirlpueixzrgitby--