summaryrefslogtreecommitdiff
path: root/lib/libusbhid
diff options
context:
space:
mode:
authorNathan Binkert <nate@cvs.openbsd.org>2002-05-10 00:09:18 +0000
committerNathan Binkert <nate@cvs.openbsd.org>2002-05-10 00:09:18 +0000
commita82d07519e6786b844ed49d488f67672db78daa2 (patch)
tree9ed579bb5297f1a9a77613ce6171eb968d7bf508 /lib/libusbhid
parent0dd51d96675add74c11132637e3499fceb185340 (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/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>