summaryrefslogtreecommitdiff
path: root/lib/libusbhid
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libusbhid')
-rw-r--r--lib/libusbhid/data.c4
-rw-r--r--lib/libusbhid/descr.c4
-rw-r--r--lib/libusbhid/parse.c147
-rw-r--r--lib/libusbhid/usage.c13
-rw-r--r--lib/libusbhid/usbhid.336
-rw-r--r--lib/libusbhid/usbhid.h16
-rw-r--r--lib/libusbhid/usbvar.h4
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>