diff options
author | Nathan Binkert <nate@cvs.openbsd.org> | 2002-05-10 00:09:18 +0000 |
---|---|---|
committer | Nathan Binkert <nate@cvs.openbsd.org> | 2002-05-10 00:09:18 +0000 |
commit | a82d07519e6786b844ed49d488f67672db78daa2 (patch) | |
tree | 9ed579bb5297f1a9a77613ce6171eb968d7bf508 /lib | |
parent | 0dd51d96675add74c11132637e3499fceb185340 (diff) |
Update usb userland stuff to reflect hid changes in the kernel.
This adds the new program usbhidaction which can be used to assign actions
to events that occur on a uhid device. For example, you can now make the
volume buttons on some newer keyboards actually do something.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libusbhid/data.c | 4 | ||||
-rw-r--r-- | lib/libusbhid/descr.c | 4 | ||||
-rw-r--r-- | lib/libusbhid/parse.c | 147 | ||||
-rw-r--r-- | lib/libusbhid/usage.c | 13 | ||||
-rw-r--r-- | lib/libusbhid/usbhid.3 | 36 | ||||
-rw-r--r-- | lib/libusbhid/usbhid.h | 16 | ||||
-rw-r--r-- | lib/libusbhid/usbvar.h | 4 |
7 files changed, 140 insertions, 84 deletions
diff --git a/lib/libusbhid/data.c b/lib/libusbhid/data.c index 57571967fe4..371fd99dfee 100644 --- a/lib/libusbhid/data.c +++ b/lib/libusbhid/data.c @@ -1,5 +1,5 @@ -/* $OpenBSD: data.c,v 1.1 2001/12/30 07:04:38 pvalchev Exp $ */ -/* $NetBSD: data.c,v 1.8 2000/04/02 11:10:53 augustss Exp $ */ +/* $OpenBSD: data.c,v 1.2 2002/05/10 00:09:17 nate Exp $ */ +/* $NetBSD: data.c,v 1.1 2001/12/28 17:45:26 augustss Exp $ */ /* * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> diff --git a/lib/libusbhid/descr.c b/lib/libusbhid/descr.c index 7366784338b..35095a406c6 100644 --- a/lib/libusbhid/descr.c +++ b/lib/libusbhid/descr.c @@ -1,5 +1,5 @@ -/* $OpenBSD: descr.c,v 1.2 2002/05/02 20:12:07 nate Exp $ */ -/* $NetBSD: descr.c,v 1.9 2000/09/24 02:13:24 augustss Exp $ */ +/* $OpenBSD: descr.c,v 1.3 2002/05/10 00:09:17 nate Exp $ */ +/* $NetBSD: descr.c,v 1.2 2002/02/20 20:31:07 christos Exp $ */ /* * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> diff --git a/lib/libusbhid/parse.c b/lib/libusbhid/parse.c index 737812254b1..4bc72344a5a 100644 --- a/lib/libusbhid/parse.c +++ b/lib/libusbhid/parse.c @@ -1,8 +1,8 @@ -/* $OpenBSD: parse.c,v 1.1 2001/12/30 07:04:38 pvalchev Exp $ */ -/* $NetBSD: parse.c,v 1.11 2000/09/24 02:19:54 augustss Exp $ */ +/* $OpenBSD: parse.c,v 1.2 2002/05/10 00:09:17 nate Exp $ */ +/* $NetBSD: parse.c,v 1.2 2001/12/29 20:44:22 augustss Exp $ */ /* - * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> + * Copyright (c) 1999, 2001 Lennart Augustsson <augustss@netbsd.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,18 +46,30 @@ struct hid_data { unsigned int usages[MAXUSAGE]; int nusage; int minset; + int logminsize; int multi; int multimax; int kindset; + int reportid; - /* 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]; + /* + * The start of collection item has no report ID set, so save + * it until we know the ID. + */ + hid_item_t savedcoll; + u_char hassavedcoll; + /* + * 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; } +static int hid_get_item_raw(hid_data_t s, hid_item_t *h); + static void hid_clear_local(hid_item_t *c) { @@ -72,17 +84,21 @@ hid_clear_local(hid_item_t *c) c->string_minimum = 0; c->string_maximum = 0; c->set_delimiter = 0; + c->report_size = 0; } hid_data_t -hid_start_parse(report_desc_t d, int kindset) +hid_start_parse(report_desc_t d, int kindset, int id) { - struct hid_data *s = malloc(sizeof *s); + struct hid_data *s; + s = malloc(sizeof *s); memset(s, 0, sizeof *s); s->start = s->p = d->data; s->end = d->data + d->size; s->kindset = kindset; + s->reportid = id; + s->hassavedcoll = 0; return (s); } @@ -101,12 +117,38 @@ hid_end_parse(hid_data_t s) int hid_get_item(hid_data_t s, hid_item_t *h) { + int r; + + for (;;) { + r = hid_get_item_raw(s, h); + if (r <= 0) + break; + if (h->report_ID == s->reportid || s->reportid == -1) + break; + } + return (r); +} + +#define REPORT_SAVED_COLL \ + do { \ + if (s->hassavedcoll) { \ + *h = s->savedcoll; \ + h->report_ID = c->report_ID; \ + s->hassavedcoll = 0; \ + return (1); \ + } \ + } while(/*LINTED*/ 0) + +static int +hid_get_item_raw(hid_data_t s, hid_item_t *h) +{ hid_item_t *c; unsigned int bTag = 0, bType = 0, bSize; unsigned char *data; int dval; unsigned char *p; hid_item_t *hi; + hid_item_t nc; int i; hid_kind_t retkind; @@ -114,13 +156,21 @@ hid_get_item(hid_data_t s, hid_item_t *h) top: if (s->multimax) { + REPORT_SAVED_COLL; + if (c->logical_minimum >= c->logical_maximum) { + if (s->logminsize == 1) + c->logical_minimum =(int8_t)c->logical_minimum; + else if (s->logminsize == 2) + c->logical_minimum =(int16_t)c->logical_minimum; + } if (s->multi < s->multimax) { c->usage = s->usages[min(s->multi, s->nusage-1)]; s->multi++; *h = *c; - - /* 'multimax' is only non-zero if the current - item kind is input/output/feature */ + /* + * '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; @@ -163,12 +213,12 @@ hid_get_item(hid_data_t s, hid_item_t *h) dval = 0; break; case 1: - dval = (int8_t)*data++; + dval = /*(int8_t)*/*data++; break; case 2: dval = *data++; dval |= *data++ << 8; - dval = (int16_t)dval; + dval = /*(int16_t)*/dval; break; case 4: dval = *data++; @@ -205,6 +255,8 @@ hid_get_item(hid_data_t s, hid_item_t *h) if (s->nusage < MAXUSAGE-1) s->nusage++; } + c->usage_minimum = 0; + c->usage_maximum = 0; s->minset = 0; } goto top; @@ -214,7 +266,8 @@ hid_get_item(hid_data_t s, hid_item_t *h) *h = *c; h->next = 0; h->pos = s->kindpos[c->kind]; - s->kindpos[c->kind] += c->report_size * c->report_count; + s->kindpos[c->kind] += + c->report_size * c->report_count; hid_clear_local(c); s->minset = 0; return (1); @@ -226,15 +279,25 @@ hid_get_item(hid_data_t s, hid_item_t *h) c->kind = hid_collection; c->collection = dval; c->collevel++; - *h = *c; + nc = *c; hid_clear_local(c); - c->report_ID = NO_REPORT_ID; + /*c->report_ID = NO_REPORT_ID;*/ s->nusage = 0; - return (1); + if (s->hassavedcoll) { + *h = s->savedcoll; + h->report_ID = nc.report_ID; + s->savedcoll = nc; + return (1); + } else { + s->hassavedcoll = 1; + s->savedcoll = nc; + } + break; case 11: /* Feature */ retkind = hid_feature; goto ret; case 12: /* End collection */ + REPORT_SAVED_COLL; c->kind = hid_endcollection; c->collevel--; *h = *c; @@ -244,6 +307,7 @@ hid_get_item(hid_data_t s, hid_item_t *h) default: return (-2); } + break; case 1: /* Global */ switch (bTag) { @@ -252,6 +316,7 @@ hid_get_item(hid_data_t s, hid_item_t *h) break; case 1: c->logical_minimum = dval; + s->logminsize = bSize; break; case 2: c->logical_maximum = dval; @@ -273,6 +338,9 @@ hid_get_item(hid_data_t s, hid_item_t *h) break; case 8: c->report_ID = dval; + s->kindpos[hid_input] = + s->kindpos[hid_output] = + s->kindpos[hid_feature] = 0; break; case 9: c->report_count = dval; @@ -294,29 +362,17 @@ hid_get_item(hid_data_t s, hid_item_t *h) case 2: /* Local */ switch (bTag) { case 0: - if (bSize == 1) - dval = c->_usage_page | (dval&0xff); - else if (bSize == 2) - dval = c->_usage_page | (dval&0xffff); - c->usage = dval; + c->usage = c->_usage_page | dval; if (s->nusage < MAXUSAGE) - s->usages[s->nusage++] = dval; + s->usages[s->nusage++] = c->usage; /* else XXX */ break; case 1: s->minset = 1; - if (bSize == 1) - dval = c->_usage_page | (dval&0xff); - else if (bSize == 2) - dval = c->_usage_page | (dval&0xffff); - c->usage_minimum = dval; + c->usage_minimum = c->_usage_page | dval; break; case 2: - if (bSize == 1) - dval = c->_usage_page | (dval&0xff); - else if (bSize == 2) - dval = c->_usage_page | (dval&0xffff); - c->usage_maximum = dval; + c->usage_maximum = c->_usage_page | dval; break; case 3: c->designator_index = dval; @@ -350,35 +406,30 @@ 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, enum hid_kind k, int id) { struct hid_data *d; hid_item_t h; - int size, id; + int size; - 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; + size = 0; + for (d = hid_start_parse(r, 1<<k, id); hid_get_item(d, &h); ) { + if (h.report_ID == id && h.kind == k) { + size = d->kindpos[k]; } } - - size = d->kindpos[k] + id; hid_end_parse(d); return ((size + 7) / 8); } int -hid_locate(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, int id) { hid_data_t d; - for (d = hid_start_parse(desc, 1<<k); hid_get_item(d, h); ) { + for (d = hid_start_parse(desc, 1<<k, id); hid_get_item(d, h); ) { if (h->kind == k && !(h->flags & HIO_CONST) && h->usage == u) { hid_end_parse(d); return (1); diff --git a/lib/libusbhid/usage.c b/lib/libusbhid/usage.c index fb36769d243..e5122c1745e 100644 --- a/lib/libusbhid/usage.c +++ b/lib/libusbhid/usage.c @@ -1,5 +1,5 @@ -/* $OpenBSD: usage.c,v 1.1 2001/12/30 07:04:38 pvalchev Exp $ */ -/* $NetBSD: usage.c,v 1.11 2001/01/09 15:59:47 augustss Exp $ */ +/* $OpenBSD: usage.c,v 1.2 2002/05/10 00:09:17 nate Exp $ */ +/* $NetBSD: usage.c,v 1.1 2001/12/28 17:45:27 augustss Exp $ */ /* * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> @@ -163,7 +163,7 @@ hid_usage_page(int i) for (k = 0; k < npages; k++) if (pages[k].usage == i) return pages[k].name; - snprintf(b, sizeof b, "0x%04x", i); + sprintf(b, "0x%04x", i); return b; } @@ -183,7 +183,7 @@ 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) { - snprintf(b, sizeof b, "%s %d", + snprintf(b, sizeof b, "%s %d", pages[k].page_contents[j].name, i); return b; } @@ -191,7 +191,7 @@ hid_usage_in_page(unsigned int u) return pages[k].page_contents[j].name; } bad: - snprintf(b, sizeof b, "0x%04x", i); + sprintf(b, "0x%04x", i); return b; } @@ -213,10 +213,11 @@ hid_parse_usage_page(const char *name) int hid_parse_usage_in_page(const char *name) { - const char *sep = strchr(name, ':'); + const char *sep; int k, j; unsigned int l; + sep = strchr(name, ':'); if (sep == NULL) return -1; l = sep - name; diff --git a/lib/libusbhid/usbhid.3 b/lib/libusbhid/usbhid.3 index 066d3a8da34..5d2c042a1dd 100644 --- a/lib/libusbhid/usbhid.3 +++ b/lib/libusbhid/usbhid.3 @@ -1,7 +1,7 @@ -.\" $OpenBSD: usbhid.3,v 1.3 2002/05/01 08:03:30 mpech Exp $ -.\" $NetBSD: usb.3,v 1.14 2001/04/09 12:09:49 wiz Exp $ +.\" $OpenBSD: usbhid.3,v 1.4 2002/05/10 00:09:17 nate Exp $ +.\" $NetBSD: usbhid.3,v 1.5 2002/02/07 07:00:52 ross Exp $ .\" -.\" Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> +.\" Copyright (c) 1999, 2001 Lennart Augustsson <augustss@netbsd.org> .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 11, 1999 +.Dd December 29, 2001 .Dt USBHID 3 .Os .Sh NAME @@ -45,7 +45,7 @@ .Nm hid_set_data .Nd USB HID access routines .Sh SYNOPSIS -.Fd #include <usbhid.h> +.Fd #include \*[Lt]usbhid.h\*[Gt] .Ft report_desc_t .Fn hid_get_report_desc "int file" .Ft report_desc_t @@ -53,15 +53,15 @@ .Ft void .Fn hid_dispose_report_desc "report_desc_t d" .Ft hid_data_t -.Fn hid_start_parse "report_desc_t d" "int kindset" +.Fn hid_start_parse "report_desc_t d" "int kindset" "int id" .Ft void .Fn hid_end_parse "hid_data_t s" .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" "hid_kind_t k" "int id" .Ft int -.Fn hid_locate "report_desc_t d" "u_int usage" "hid_kind_t k" "hid_item_t *h" +.Fn hid_locate "report_desc_t d" "u_int usage" "hid_kind_t k" "hid_item_t *h" "int id" .Ft char * .Fn hid_usage_page "int i" .Ft char * @@ -115,11 +115,13 @@ To parse the report descriptor the function should be called with a report descriptor and a set that describes which items that are interesting. The set is obtained by or-ing together values -.Fa "(1 << k)" +.Fa "(1 \*[Lt]\*[Lt] k)" where .Fa k is an item of type .Fa hid_kind_t . +The report id (if present) is given by +.Fa id . The function returns .Fa NULL if the initialization fails, otherwise an opaque value to be used @@ -140,7 +142,7 @@ will be filled with the relevant data for the item. The definition of .Fa hid_item_t can be found in -.Pa <usbhid.h> +.Pa \*[Lt]usbhid.h\*[Gt] and the meaning of the components in the USB HID documentation. .Pp Data should be read/written to the device in the size of @@ -148,9 +150,8 @@ 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. +If the report is prefixed by an ID byte it is given by +.Fa id . .Pp To locate a single item the .Fn hid_locate @@ -192,18 +193,15 @@ function extracts the value of the item. Conversely .Fn hid_set_data can be used to put data into a report (which must be zeroed first). -.Sh EXAMPLES -Not yet. .Sh FILES .Pa /usr/share/misc/usb_hid_usages The default HID usage table. -.Sh BUGS -This man page is woefully incomplete. +.\" .Sh EXAMPLES .Sh SEE ALSO The .Tn USB specifications can be found at: -.Dv http://www.usb.org/developers/docs.html +.Dv http://www.usb.org/developers/docs.html . .Pp .Xr uhid 4 , .Xr usb 4 @@ -212,3 +210,5 @@ The .Nm library first appeared in .Ox 3.0 . +.Sh BUGS +This man page is woefully incomplete. diff --git a/lib/libusbhid/usbhid.h b/lib/libusbhid/usbhid.h index 57c0b83bde9..7172ca5fac8 100644 --- a/lib/libusbhid/usbhid.h +++ b/lib/libusbhid/usbhid.h @@ -1,4 +1,4 @@ -/* $OpenBSD: usbhid.h,v 1.1 2001/12/30 07:04:38 pvalchev Exp $ */ +/* $OpenBSD: usbhid.h,v 1.2 2002/05/10 00:09:17 nate Exp $ */ /* $NetBSD: usbhid.h,v 1.1 2001/12/28 17:45:27 augustss Exp $ */ /* @@ -32,8 +32,12 @@ typedef struct report_desc *report_desc_t; 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_input = 0, + hid_output = 1, + hid_feature = 2, + hid_collection, + hid_endcollection +} hid_kind_t; typedef struct hid_item { /* Global */ @@ -79,11 +83,11 @@ report_desc_t hid_use_report_desc(unsigned char *data, unsigned int size); void hid_dispose_report_desc(report_desc_t); /* Parsing of a HID report descriptor, parse.c: */ -hid_data_t hid_start_parse(report_desc_t d, int kindset); +hid_data_t hid_start_parse(report_desc_t d, int kindset, int id); void hid_end_parse(hid_data_t s); int hid_get_item(hid_data_t s, hid_item_t *h); -int hid_report_size(report_desc_t d, enum hid_kind k, int *idp); -int hid_locate(report_desc_t d, unsigned int usage, enum hid_kind k, hid_item_t *h); +int hid_report_size(report_desc_t d, enum hid_kind k, int id); +int hid_locate(report_desc_t d, unsigned int usage, enum hid_kind k, hid_item_t *h, int id); /* Conversion to/from usage names, usage.c: */ const char *hid_usage_page(int i); diff --git a/lib/libusbhid/usbvar.h b/lib/libusbhid/usbvar.h index ef23a3d3bfa..224423ea99f 100644 --- a/lib/libusbhid/usbvar.h +++ b/lib/libusbhid/usbvar.h @@ -1,5 +1,5 @@ -/* $OpenBSD: usbvar.h,v 1.1 2001/12/30 07:04:38 pvalchev Exp $ */ -/* $NetBSD: usbvar.h,v 1.2 1999/05/11 21:15:46 augustss Exp $ */ +/* $OpenBSD: usbvar.h,v 1.2 2002/05/10 00:09:17 nate Exp $ */ +/* $NetBSD: usbvar.h,v 1.1 2001/12/28 17:45:27 augustss Exp $ */ /* * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> |