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/libusb | |
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/libusb')
-rw-r--r-- | lib/libusb/descr.c | 30 | ||||
-rw-r--r-- | lib/libusb/libusb.h | 5 | ||||
-rw-r--r-- | lib/libusb/parse.c | 72 | ||||
-rw-r--r-- | lib/libusb/usage.c | 42 | ||||
-rw-r--r-- | lib/libusb/usb.3 | 42 |
5 files changed, 132 insertions, 59 deletions
diff --git a/lib/libusb/descr.c b/lib/libusb/descr.c index 8904a87..65b60ce 100644 --- a/lib/libusb/descr.c +++ b/lib/libusb/descr.c @@ -1,4 +1,4 @@ -/* $NetBSD: descr.c,v 1.7 1999/10/13 17:48:04 drochner Exp $ */ +/* $NetBSD: descr.c,v 1.9 2000/09/24 02:13:24 augustss Exp $ */ /* * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> @@ -37,7 +37,9 @@ #include <string.h> #include <unistd.h> #include <sys/time.h> +#if defined(__FreeBSD__) #include <sys/ioctl.h> +#endif #include <dev/usb/usb.h> @@ -45,28 +47,34 @@ #include "usbvar.h" report_desc_t -hid_get_report_desc(fd) - int fd; +hid_get_report_desc(int fd) { struct usb_ctl_report_desc rep; - report_desc_t r; rep.size = 0; if (ioctl(fd, USB_GET_REPORT_DESC, &rep) < 0) - return (0); - r = malloc(sizeof *r + rep.size); + return (NULL); + + return hid_use_report_desc(rep.data, (unsigned int)rep.size); +} + +report_desc_t +hid_use_report_desc(unsigned char *data, unsigned int size) +{ + report_desc_t r; + + r = malloc(sizeof(*r) + size); if (r == 0) { errno = ENOMEM; - return (0); + return (NULL); } - r->size = rep.size; - memcpy(r->data, rep.data, (unsigned int)rep.size); + r->size = size; + memcpy(r->data, data, size); return (r); } void -hid_dispose_report_desc(r) - report_desc_t r; +hid_dispose_report_desc(report_desc_t r) { free(r); diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h index 854eda8..7d4ac20 100644 --- a/lib/libusb/libusb.h +++ b/lib/libusb/libusb.h @@ -35,7 +35,7 @@ typedef struct hid_data *hid_data_t; typedef enum hid_kind { hid_input, hid_output, hid_feature, hid_collection, hid_endcollection -}hid_kind_t; +} hid_kind_t; typedef struct hid_item { /* Global */ @@ -77,13 +77,14 @@ typedef struct hid_item { /* Obtaining a report descriptor, descr.c: */ report_desc_t hid_get_report_desc __P((int file)); +report_desc_t hid_use_report_desc __P((unsigned char *data, unsigned int size)); void hid_dispose_report_desc __P((report_desc_t)); /* Parsing of a HID report descriptor, parse.c: */ hid_data_t hid_start_parse __P((report_desc_t d, int kindset)); void hid_end_parse __P((hid_data_t s)); int hid_get_item __P((hid_data_t s, hid_item_t *h)); -int hid_report_size __P((report_desc_t d, enum hid_kind k, int *idp)); +int hid_report_size __P((report_desc_t d, unsigned int id, enum hid_kind k)); int hid_locate __P((report_desc_t d, unsigned int usage, enum hid_kind k, hid_item_t *h)); /* Conversion to/from usage names, usage.c: */ diff --git a/lib/libusb/parse.c b/lib/libusb/parse.c index f021762..da4c974 100644 --- a/lib/libusb/parse.c +++ b/lib/libusb/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; diff --git a/lib/libusb/usage.c b/lib/libusb/usage.c index 28d8c3b..7e71bff 100644 --- a/lib/libusb/usage.c +++ b/lib/libusb/usage.c @@ -1,4 +1,4 @@ -/* $NetBSD: usage.c,v 1.6 2000/08/13 22:22:02 augustss Exp $ */ +/* $NetBSD: usage.c,v 1.8 2000/10/10 19:23:58 is Exp $ */ /* * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> @@ -185,7 +185,8 @@ hid_usage_in_page(unsigned int u) for (j = 0; j < pages[k].pagesize; j++) { us = pages[k].page_contents[j].usage; if (us == -1) { - sprintf(b, pages[k].page_contents[j].name, i); + sprintf(b, "%s %d", + pages[k].page_contents[j].name, i); return b; } if (us == i) @@ -195,3 +196,40 @@ hid_usage_in_page(unsigned int u) sprintf(b, "0x%04x", i); return b; } + +int +hid_parse_usage_page(const char *name) +{ + int k; + + if (!pages) + errx(1, "no hid table\n"); + + for (k = 0; k < npages; k++) + if (strcmp(pages[k].name, name) == 0) + return pages[k].usage; + return -1; +} + +/* XXX handle hex */ +int +hid_parse_usage_in_page(const char *name) +{ + const char *sep = strchr(name, ':'); + int k, j; + unsigned int l; + + if (sep == NULL) + return -1; + l = sep - name; + for (k = 0; k < npages; k++) + if (strncmp(pages[k].name, name, l) == 0) + goto found; + return -1; + found: + sep++; + for (j = 0; j < pages[k].pagesize; j++) + if (strcmp(pages[k].page_contents[j].name, sep) == 0) + return (pages[k].usage << 16) | pages[k].page_contents[j].usage; + return (-1); +} diff --git a/lib/libusb/usb.3 b/lib/libusb/usb.3 index a8a8753..6bcf696 100644 --- a/lib/libusb/usb.3 +++ b/lib/libusb/usb.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: usb.3,v 1.10 2000/02/22 12:39:22 augustss Exp $ +.\" $NetBSD: usb.3,v 1.13 2000/09/24 02:17:52 augustss Exp $ .\" $FreeBSD$ .\" .\" Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> @@ -31,6 +31,7 @@ .Sh NAME .Nm usb , .Nm hid_get_report_desc , +.Nm hid_use_report_desc , .Nm hid_dispose_report_desc , .Nm hid_start_parse , .Nm hid_end_parse , @@ -49,6 +50,8 @@ .Fd #include <libusb.h> .Ft report_desc_t .Fn hid_get_report_desc "int file" +.Ft report_desc_t +.Fn hid_use_report_desc "unsigned char *data" "unsigned int size" .Ft void .Fn hid_dispose_report_desc "report_desc_t d" .Ft hid_data_t @@ -58,13 +61,17 @@ .Ft int .Fn hid_get_item "hid_data_t s" "hid_item_t *h" .Ft int -.Fn hid_report_size "report_desc_t d" "hid_kind_t k" "int *idp" +.Fn hid_report_size "report_desc_t d" "unsigned int id" "hid_kind_t k" .Ft int .Fn hid_locate "report_desc_t d" "u_int usage" "hid_kind_t k" "hid_item_t *h" .Ft char * .Fn hid_usage_page "int i" .Ft char * .Fn hid_usage_in_page "u_int u" +.Ft int +.Fn hid_parse_usage_page "const char *" +.Ft char * +.Fn hid_parse_usage_in_page "const char *" .Ft void .Fn hid_init "char *file" .Ft int @@ -91,13 +98,19 @@ A report descriptor can be obtained by calling .Fn hid_get_report_desc with a file descriptor obtained by opening a .Xr uhid 4 -device. -When the report descriptor is no longer needed it should be freed -by calling +device. Alternatively a data buffer containing the report descriptor can be +passed into +.Fn hid_use_report_desc . +The data is copied into an internal structure. When the report descriptor +is no longer needed it should be freed by calling .Fn hid_dispose_report_desc . The type .Fa report_desc_t is opaque and should be used when calling the parsing functions. +If +.Fn hid_dispose_report_desc +fails it will return +.Fa NULL . .Ss DESCRIPTOR PARSING FUNCTIONS To parse the report descriptor the .Fn hid_start_parse @@ -136,10 +149,7 @@ Data should be read/written to the device in the size of the report. The size of a report (of a certain kind) can be computed by the .Fn hid_report_size -function. If the report is prefixed by an ID byte it is -stored at -.Fa idp , -otherwise it will contain 0. +function. .Pp To locate a single item the .Fn hid_locate @@ -154,7 +164,19 @@ will return the symbolic name of a usage page, and the function .Fn hid_usage_in_page will return the symbolic name of the usage within the page. Both these functions may return a pointer to static data. -Before either of these functions can be called the usage table +.Pp +The functions +.Fn hid_parse_usage_page +and +.Fn hid_parse_usage_in_page +are the inverses of +.Fn hid_usage_page +and +.Fn hid_usage_in_page . +They take a usage string and return the number of the usage, or -1 +if it cannot be found. +.Pp +Before any of these functions can be called the usage table must be parsed, this is done by calling .Fn hid_init with the name of the table. Passing |