diff options
author | n_hibma <n_hibma@FreeBSD.org> | 2000-10-16 18:13:59 +0000 |
---|---|---|
committer | n_hibma <n_hibma@FreeBSD.org> | 2000-10-16 18:13:59 +0000 |
commit | ef4994a1212dd74d2ea9e3be4b586433d2aeb0bd (patch) | |
tree | f5bf67808c38fb5703446a339a4b2fbee87bfa91 /lib/libusbhid/parse.c | |
parent | ba11a89d00cdc5eb8917da96d66e9feae77dc5e6 (diff) | |
download | FreeBSD-src-ef4994a1212dd74d2ea9e3be4b586433d2aeb0bd.zip FreeBSD-src-ef4994a1212dd74d2ea9e3be4b586433d2aeb0bd.tar.gz |
Sync with NetBSD:
K&R -> ANSI
Bugfix: 'Keep the bit position even when the report descriptor says POP.'
Add hid_use_report_desc, hid_parse_usage_page, hid_parse_usage_in_page.
Changed iface for hid_report_size.
Diffstat (limited to 'lib/libusbhid/parse.c')
-rw-r--r-- | lib/libusbhid/parse.c | 72 |
1 files changed, 38 insertions, 34 deletions
diff --git a/lib/libusbhid/parse.c b/lib/libusbhid/parse.c index f021762..da4c974 100644 --- a/lib/libusbhid/parse.c +++ b/lib/libusbhid/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.9 2000/03/17 18:09:17 augustss Exp $ */ +/* $NetBSD: parse.c,v 1.11 2000/09/24 02:19:54 augustss Exp $ */ /* * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> @@ -52,6 +52,11 @@ struct hid_data { int multi; int multimax; int kindset; + + /* Absolute data position (bits) for input/output/feature. + Assumes that hid_input, hid_output and hid_feature have + values 0, 1 and 2. */ + unsigned int kindpos[3]; }; static int min(int x, int y) { return x < y ? x : y; } @@ -99,12 +104,13 @@ int hid_get_item(hid_data_t s, hid_item_t *h) { hid_item_t *c; - unsigned int bTag = 0, bType = 0, bSize, oldpos; + unsigned int bTag = 0, bType = 0, bSize; unsigned char *data; int dval; unsigned char *p; hid_item_t *hi; int i; + hid_kind_t retkind; c = &s->cur; @@ -114,7 +120,11 @@ hid_get_item(hid_data_t s, hid_item_t *h) c->usage = s->usages[min(s->multi, s->nusage-1)]; s->multi++; *h = *c; - c->pos += c->report_size; + + /* 'multimax' is only non-zero if the current + item kind is input/output/feature */ + h->pos = s->kindpos[c->kind]; + s->kindpos[c->kind] += c->report_size; h->next = 0; return (1); } else { @@ -176,11 +186,15 @@ hid_get_item(hid_data_t s, hid_item_t *h) case 0: /* Main */ switch (bTag) { case 8: /* Input */ - if (!(s->kindset & (1 << hid_input))) + retkind = hid_input; + ret: + if (!(s->kindset & (1 << retkind))) { + /* Drop the items of this kind */ + s->nusage = 0; continue; - c->kind = hid_input; + } + c->kind = retkind; c->flags = dval; - ret: if (c->flags & HIO_VARIABLE) { s->multimax = c->report_count; s->multi = 0; @@ -201,16 +215,14 @@ hid_get_item(hid_data_t s, hid_item_t *h) c->usage = c->usage_minimum; *h = *c; h->next = 0; - c->pos += c->report_size * c->report_count; + h->pos = s->kindpos[c->kind]; + s->kindpos[c->kind] += c->report_size * c->report_count; hid_clear_local(c); s->minset = 0; return (1); } case 9: /* Output */ - if (!(s->kindset & (1 << hid_output))) - continue; - c->kind = hid_output; - c->flags = dval; + retkind = hid_output; goto ret; case 10: /* Collection */ c->kind = hid_collection; @@ -222,10 +234,7 @@ hid_get_item(hid_data_t s, hid_item_t *h) s->nusage = 0; return (1); case 11: /* Feature */ - if (!(s->kindset & (1 << hid_feature))) - continue; - c->kind = hid_feature; - c->flags = dval; + retkind = hid_feature; goto ret; case 12: /* End collection */ c->kind = hid_endcollection; @@ -277,9 +286,7 @@ hid_get_item(hid_data_t s, hid_item_t *h) break; case 11: /* Pop */ hi = c->next; - oldpos = c->pos; s->cur = *hi; - c->pos = oldpos; free(hi); break; default: @@ -345,34 +352,31 @@ hid_get_item(hid_data_t s, hid_item_t *h) } int -hid_report_size(report_desc_t r, enum hid_kind k, int *idp) +hid_report_size(report_desc_t r, unsigned int id, enum hid_kind k) { struct hid_data *d; hid_item_t h; - int size, id; + unsigned int size = 0; - id = 0; - if (idp) - *idp = 0; memset(&h, 0, sizeof h); - for (d = hid_start_parse(r, 1<<k); hid_get_item(d, &h); ) { - if (h.report_ID != NO_REPORT_ID) { - if (idp) - *idp = h.report_ID; - id = 8; + d = hid_start_parse(r, 1<<k); + while (hid_get_item(d, &h)) { + if (h.report_ID == id && h.kind == k) { + unsigned int newsize = h.pos + h.report_size; + if (newsize > size) + size = newsize; } } hid_end_parse(d); - size = h.pos + id; - return ((size + 7) / 8); + + if (id != NO_REPORT_ID) + size += 8; /* add 8 bits for the report ID */ + + return ((size + 7) / 8); /* return size in bytes */ } int -hid_locate(desc, u, k, h) - report_desc_t desc; - unsigned int u; - enum hid_kind k; - hid_item_t *h; +hid_locate(report_desc_t desc, unsigned int u, enum hid_kind k, hid_item_t *h) { hid_data_t d; |