aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libusb/descr.c30
-rw-r--r--lib/libusb/libusb.h5
-rw-r--r--lib/libusb/parse.c72
-rw-r--r--lib/libusb/usage.c42
-rw-r--r--lib/libusb/usb.342
-rw-r--r--lib/libusbhid/descr.c30
-rw-r--r--lib/libusbhid/libusb.h5
-rw-r--r--lib/libusbhid/libusbhid.h5
-rw-r--r--lib/libusbhid/parse.c72
-rw-r--r--lib/libusbhid/usage.c42
-rw-r--r--lib/libusbhid/usb.342
-rw-r--r--lib/libusbhid/usbhid.342
-rw-r--r--lib/libusbhid/usbhid.h5
13 files changed, 302 insertions, 132 deletions
diff --git a/lib/libusb/descr.c b/lib/libusb/descr.c
index 8904a871cb11..65b60ce78b82 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 854eda87704b..7d4ac20d3e5e 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 f021762e2003..da4c974980a1 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 28d8c3bcdf36..7e71bff1289d 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 a8a87534914b..6bcf696db2fe 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
diff --git a/lib/libusbhid/descr.c b/lib/libusbhid/descr.c
index 8904a871cb11..65b60ce78b82 100644
--- a/lib/libusbhid/descr.c
+++ b/lib/libusbhid/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/libusbhid/libusb.h b/lib/libusbhid/libusb.h
index 854eda87704b..7d4ac20d3e5e 100644
--- a/lib/libusbhid/libusb.h
+++ b/lib/libusbhid/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/libusbhid/libusbhid.h b/lib/libusbhid/libusbhid.h
index 854eda87704b..7d4ac20d3e5e 100644
--- a/lib/libusbhid/libusbhid.h
+++ b/lib/libusbhid/libusbhid.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/libusbhid/parse.c b/lib/libusbhid/parse.c
index f021762e2003..da4c974980a1 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;
diff --git a/lib/libusbhid/usage.c b/lib/libusbhid/usage.c
index 28d8c3bcdf36..7e71bff1289d 100644
--- a/lib/libusbhid/usage.c
+++ b/lib/libusbhid/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/libusbhid/usb.3 b/lib/libusbhid/usb.3
index a8a87534914b..6bcf696db2fe 100644
--- a/lib/libusbhid/usb.3
+++ b/lib/libusbhid/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
diff --git a/lib/libusbhid/usbhid.3 b/lib/libusbhid/usbhid.3
index a8a87534914b..6bcf696db2fe 100644
--- a/lib/libusbhid/usbhid.3
+++ b/lib/libusbhid/usbhid.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
diff --git a/lib/libusbhid/usbhid.h b/lib/libusbhid/usbhid.h
index 854eda87704b..7d4ac20d3e5e 100644
--- a/lib/libusbhid/usbhid.h
+++ b/lib/libusbhid/usbhid.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: */