problem with libusbhid?

Chuck Robey chuckr at
Sat May 24 16:55:26 UTC 2008

Hash: SHA1

I'm not totally sure, I could well just be using the library wrong (I had a lot
of trouble making sense of the man page), but I'm going to suggest that I might
have found a problem, and *IF* it *IS* a problem, I'm going to suggest how I
would fix it.

I wrote a little C program, to list out all of the usb hid_item struct, and it
nicely printed out all the fields, one by one, with the single exception of the
_usage page.  My device is a graphic tablet, and it should have given me the
usage page (DIGITIZER), but instead it gave me "13" which is the decimal value
of that page.  I think that the code in usage.c ought to be patched as I did
below, so that it correctly lists the name of the usage page, and not it's number:

cvs diff: Diffing .
Index: usage.c
RCS file: /home/ncvs/src/lib/libusbhid/usage.c,v
retrieving revision 1.8
diff -u -r1.8 usage.c
- --- usage.c     9 Apr 2003 01:52:48 -0000       1.8
+++ usage.c     24 May 2008 16:34:17 -0000
@@ -164,7 +164,7 @@
                errx(1, "no hid table");

        for (k = 0; k < npages; k++)
- -               if (pages[k].usage == i)
+               if (pages[k].usage == HID_PAGE(i))
                        return pages[k].name;
        sprintf(b, "0x%04x", i);
        return b;

I have a test program I wrote for it, I might as well stick it in the end here
because it's pretty small (I couldn't get that last printf to compile, anyone
know why?)  Normally I would have attached the program and diff, but I've found
that attachments get stripped out of mail, so sorry about the mailer folding lines:

#include <stdio.h>
#include <fcntl.h>
#include <usbhid.h>
#include <stdlib.h>

void printhid( hid_item_t );
void runparse(report_desc_t, int);

int main( int argc, char *argv[] ){
        int udev, hidItem, hsize, i;
        report_desc_t hidrpt;

        udev = open("/dev/uhid0", O_RDWR);
        hidrpt = hid_get_report_desc(udev);

        for(i=7; i<10; i++) runparse(hidrpt, i);


void runparse(report_desc_t h, int id) {
        hid_data_t hs;
        hid_item_t gs;
        int hidItem;

        hs = hid_start_parse(h, 31, id );
        printf("\tBeginning parse run for %d\n", id);
        while(hidItem = hid_get_item(hs, &gs)!= 0)
        printf("\tEnding parse run for %d\n\n\n", id);

void printhid(hid_item_t gs) {
        printf("hid_data_t._usage_page %d:%s\n",gs._usage_page,
        printf("hid_data_t.logical_minimum %d\n",gs.logical_minimum);
        printf("hid_data_t.logical_maximum %d\n",gs.logical_maximum);
        printf("hid_data_t.physical_minimum %d\n",gs.physical_minimum);
        printf("hid_data_t.unit_exponent %d\n",gs.unit_exponent);
        printf("hid_data_t.unit %d\n",gs.unit);
        printf("hid_data_t.report_ID %d\n",gs.report_ID);
        printf("hid_data_t.usage %d:%s\n",gs.usage, hid_usage_in_page(gs.usage));
        printf("hid_data_t.usage_minimum %d\n",gs.usage_minimum);
        printf("hid_data_t.usage_maximum %d\n",gs.usage_maximum);
        printf("hid_data_t.designator_index %d\n",gs.designator_index);
        printf("hid_data_t.designator_minimum %d\n",gs.designator_minimum);
        printf("hid_data_t.designator_maximum %d\n",gs.designator_maximum);
        printf("hid_data_t.logical_minimum %d\n",gs.logical_minimum);
        printf("hid_data_t.string_index %d\n",gs.string_index);
        printf("hid_data_t.string_minimum %d\n",gs.string_minimum);
        printf("hid_data_t.string_maximum %d\n",gs.string_maximum);
        printf("hid_data_t.set_delimiter %d\n",gs.set_delimiter);
        printf("hid_data_t.collection %d\n",gs.collection);
        printf("hid_data_t.collevel %d\n",gs.collevel);
        printf("hid_data_t.kind %d\n",gs.kind);
        printf("hid_data_t.flags %d\n",gs.flags);
        //printf("hid_data_t.loc.size %X\n",gs.loc.size);
Version: GnuPG v2.0.4 (FreeBSD)
Comment: Using GnuPG with Mozilla -


More information about the freebsd-usb mailing list