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.
This commit is contained in:
parent
ba11a89d00
commit
ef4994a121
@ -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);
|
||||
|
@ -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: */
|
||||
|
@ -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)))
|
||||
continue;
|
||||
c->kind = hid_input;
|
||||
c->flags = dval;
|
||||
retkind = hid_input;
|
||||
ret:
|
||||
if (!(s->kindset & (1 << retkind))) {
|
||||
/* Drop the items of this kind */
|
||||
s->nusage = 0;
|
||||
continue;
|
||||
}
|
||||
c->kind = retkind;
|
||||
c->flags = dval;
|
||||
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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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: */
|
||||
|
@ -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: */
|
||||
|
@ -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)))
|
||||
continue;
|
||||
c->kind = hid_input;
|
||||
c->flags = dval;
|
||||
retkind = hid_input;
|
||||
ret:
|
||||
if (!(s->kindset & (1 << retkind))) {
|
||||
/* Drop the items of this kind */
|
||||
s->nusage = 0;
|
||||
continue;
|
||||
}
|
||||
c->kind = retkind;
|
||||
c->flags = dval;
|
||||
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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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: */
|
||||
|
Loading…
Reference in New Issue
Block a user