Merge branch 'master' of github.com:signal11/hidapi

This commit is contained in:
Alan Ott 2010-07-24 11:06:29 -04:00
commit a55cfb7674
3 changed files with 77 additions and 195 deletions

View File

@ -27,7 +27,10 @@
#ifdef __cplusplus
extern "C" {
#endif
struct hid_device {
struct hid_device_;
typedef struct hid_device_ hid_device;
struct hid_device_info {
/** Platform-specific device path */
char *path;
/** Device Vendor ID */
@ -42,7 +45,7 @@ extern "C" {
wchar_t *product_string;
/** Pointer to the next device */
struct hid_device *next;
struct hid_device_info *next;
};
@ -62,7 +65,7 @@ extern "C" {
attached to the system, or NULL in the case of failure. Free
this linked list by calling hid_free_enumeration().
*/
struct hid_device HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id);
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id);
/** Free an enumeration Linked List
This function frees a linked list created by hid_enumerate().
@ -75,7 +78,7 @@ extern "C" {
This function does not return a value.
*/
void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device *devs);
void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs);
/** Open a HID device using a Vendor ID (VID), Product ID (PID) and
optionally a serial number. If serial_number is NULL, the first
@ -88,10 +91,10 @@ extern "C" {
(Optionally NULL).
Return:
This function returns a small integer handle on success
and -1 on failure.
This function returns a pointer to a hid_device object on
success or NULL on failure.
*/
int HID_API_EXPORT HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number);
HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number);
/** Open a HID device by its path name. The path name be determined
by calling hid_enumerate(), or a platform-specific path name can
@ -101,10 +104,10 @@ extern "C" {
path: The path name of the device to open
Return:
This function returns a small integer handle on success
and -1 on failure.
This function returns a pointer to a hid_device object on
success or NULL on failure.
*/
int HID_API_EXPORT HID_API_CALL hid_open_path(const char *path);
HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path);
/** Write an Output report to a HID device. The first byte of data[]
must contain the Report ID. For devices which only support a single
@ -130,7 +133,7 @@ extern "C" {
This function returns the actual number of bytes written and
-1 on error.
*/
int HID_API_EXPORT HID_API_CALL hid_write(int device, const unsigned char *data, size_t length);
int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length);
/** Read an Input report from a HID device. Input reports are returned
to the host through the INTERRUPT IN endpoint. The first byte will
@ -147,7 +150,7 @@ extern "C" {
This function returns the actual number of bytes read and
-1 on error.
*/
int HID_API_EXPORT HID_API_CALL hid_read(int device, unsigned char *data, size_t length);
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length);
/** Set the device handle to be non-blocking. In non-blocking mode
calls to hid_read() will return immediately with a value of 0
@ -164,7 +167,7 @@ extern "C" {
Return Value:
This function returns 0 on success and -1 on error.
*/
int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(int device, int nonblock);
int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock);
/** Send a Feature report to the device. Feature reports are sent
over the Control endpoint as a Set_Report transfer. The first
@ -189,7 +192,7 @@ extern "C" {
This function returns the actual number of bytes written and
-1 on error.
*/
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(int device, const unsigned char *data, size_t length);
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length);
/** Get a feature report from a HID device. Make sure to set the
first byte of data[] to the Report ID of the report to be read.
@ -207,14 +210,14 @@ extern "C" {
Return Value:
This function returns 0 on success and -1 on error.
*/
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(int device, unsigned char *data, size_t length);
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length);
/** Close a HID device.
Params:
device: A device handle returned from hid_open().
*/
void HID_API_EXPORT HID_API_CALL hid_close(int device);
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device);
/** Get The Manufacturer String from a HID device.
@ -226,7 +229,7 @@ extern "C" {
Return Value:
This function returns 0 on success and -1 on error.
*/
int HID_API_EXPORT_CALL hid_get_manufacturer_string(int device, wchar_t *string, size_t maxlen);
int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen);
/** Get The Product String from a HID device.
@ -238,7 +241,7 @@ extern "C" {
Return Value:
This function returns 0 on success and -1 on error.
*/
int HID_API_EXPORT_CALL hid_get_product_string(int device, wchar_t *string, size_t maxlen);
int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen);
/** Get The Serial Number String from a HID device.
@ -250,7 +253,7 @@ extern "C" {
Return Value:
This function returns 0 on success and -1 on error.
*/
int HID_API_EXPORT_CALL hid_get_serial_number_string(int device, wchar_t *string, size_t maxlen);
int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen);
/** Get a string from a HID device, based on its string index.
@ -263,7 +266,7 @@ extern "C" {
Return Value:
This function returns 0 on success and -1 on error.
*/
int HID_API_EXPORT_CALL hid_get_indexed_string(int device, int string_index, wchar_t *string, size_t maxlen);
int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen);
/** Get a string describing the last error which occurred.
@ -274,7 +277,7 @@ extern "C" {
This function returns a string containing the last error
which occurred or NULL if none has occurred.
*/
HID_API_EXPORT const char* HID_API_CALL hid_error(int device);
HID_API_EXPORT const char* HID_API_CALL hid_error(hid_device *device);
#ifdef __cplusplus
}

View File

@ -35,20 +35,26 @@
#include "hidapi.h"
struct Device {
int valid;
struct hid_device_ {
int device_handle;
int blocking;
int uses_numbered_reports;
};
#define MAX_DEVICES 64
static struct Device devices[MAX_DEVICES];
static int devices_initialized = 0;
static __u32 kernel_version = 0;
static void register_error(struct Device *device, const char *op)
hid_device *new_hid_device()
{
hid_device *dev = calloc(1, sizeof(hid_device));
dev->device_handle = -1;
dev->blocking = 1;
dev->uses_numbered_reports = 0;
return dev;
}
static void register_error(hid_device *device, const char *op)
{
}
@ -83,7 +89,7 @@ static int uses_numbered_reports(__u8 *report_descriptor, __u32 size) {
/* Check for the Report ID key */
if (key == 0x85/*Report ID*/) {
/* This devices has a Report ID, which means it uses
/* This device has a Report ID, which means it uses
numbered reports. */
return 1;
}
@ -133,7 +139,7 @@ static int uses_numbered_reports(__u8 *report_descriptor, __u32 size) {
return 0;
}
static int get_device_string(struct Device *dev, const char *key, wchar_t *string, size_t maxlen)
static int get_device_string(hid_device *dev, const char *key, wchar_t *string, size_t maxlen)
{
struct udev *udev;
struct udev_device *udev_dev, *parent;
@ -180,15 +186,15 @@ end:
}
struct hid_device HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
struct udev *udev;
struct udev_enumerate *enumerate;
struct udev_list_entry *devices, *dev_list_entry;
struct udev_device *dev;
struct hid_device *root = NULL; // return object
struct hid_device *cur_dev = NULL;
struct hid_device_info *root = NULL; // return object
struct hid_device_info *cur_dev = NULL;
setlocale(LC_ALL,"");
@ -243,11 +249,11 @@ struct hid_device HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsig
/* Check the VID/PID against the arguments */
if ((vendor_id == 0x0 && product_id == 0x0) ||
(vendor_id == dev_vid && product_id == dev_pid)) {
struct hid_device *tmp;
struct hid_device_info *tmp;
size_t len;
/* VID/PID match. Create the record. */
tmp = malloc(sizeof(struct hid_device));
tmp = malloc(sizeof(struct hid_device_info));
if (cur_dev) {
cur_dev->next = tmp;
}
@ -295,11 +301,11 @@ struct hid_device HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsig
return root;
}
void HID_API_EXPORT hid_free_enumeration(struct hid_device *devs)
void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
{
struct hid_device *d = devs;
struct hid_device_info *d = devs;
while (d) {
struct hid_device *next = d->next;
struct hid_device_info *next = d->next;
free(d->path);
free(d->serial_number);
free(d->manufacturer_string);
@ -309,11 +315,11 @@ void HID_API_EXPORT hid_free_enumeration(struct hid_device *devs)
}
}
int HID_API_EXPORT hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number)
hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number)
{
struct hid_device *devs, *cur_dev;
struct hid_device_info *devs, *cur_dev;
const char *path_to_open = NULL;
int handle = -1;
hid_device *handle = NULL;
devs = hid_enumerate(vendor_id, product_id);
cur_dev = devs;
@ -344,41 +350,13 @@ int HID_API_EXPORT hid_open(unsigned short vendor_id, unsigned short product_id,
return handle;
}
int HID_API_EXPORT hid_open_path(const char *path)
hid_device * HID_API_EXPORT hid_open_path(const char *path)
{
int i;
int handle = -1;
struct Device *dev = NULL;
hid_device *dev = NULL;
// Initialize the Device array if it hasn't been done.
if (!devices_initialized) {
int i;
for (i = 0; i < MAX_DEVICES; i++) {
devices[i].valid = 0;
devices[i].device_handle = -1;
devices[i].blocking = 1;
devices[i].uses_numbered_reports = 0;
}
devices_initialized = 1;
}
dev = new_hid_device();
// Find an available handle to use;
for (i = 0; i < MAX_DEVICES; i++) {
if (!devices[i].valid) {
devices[i].valid = 1;
devices[i].device_handle = -1;
devices[i].blocking = 1;
devices[i].uses_numbered_reports = 0;
handle = i;
dev = &devices[i];
break;
}
}
if (handle < 0) {
return -1;
}
if (kernel_version == 0) {
struct utsname name;
int major, minor, release;
@ -426,46 +404,30 @@ int HID_API_EXPORT hid_open_path(const char *path)
rpt_desc.size);
}
return handle;
return dev;
}
else {
// Unable to open any devices.
dev->valid = 0;
return -1;
free(dev);
return NULL;
}
}
int HID_API_EXPORT hid_write(int device, const unsigned char *data, size_t length)
int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
{
struct Device *dev = NULL;
int bytes_written;
// Get the handle
if (device < 0 || device >= MAX_DEVICES)
return -1;
if (devices[device].valid == 0)
return -1;
dev = &devices[device];
bytes_written = write(dev->device_handle, data, length);
return bytes_written;
}
int HID_API_EXPORT hid_read(int device, unsigned char *data, size_t length)
int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
{
struct Device *dev = NULL;
int bytes_read;
// Get the handle
if (device < 0 || device >= MAX_DEVICES)
return -1;
if (devices[device].valid == 0)
return -1;
dev = &devices[device];
bytes_read = read(dev->device_handle, data, length);
if (bytes_read < 0 && errno == EAGAIN)
bytes_read = 0;
@ -481,18 +443,10 @@ int HID_API_EXPORT hid_read(int device, unsigned char *data, size_t length)
return bytes_read;
}
int HID_API_EXPORT hid_set_nonblocking(int device, int nonblock)
int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
{
int flags, res;
struct Device *dev = NULL;
// Get the handle
if (device < 0 || device >= MAX_DEVICES)
return -1;
if (devices[device].valid == 0)
return -1;
dev = &devices[device];
flags = fcntl(dev->device_handle, F_GETFL, 0);
if (flags >= 0) {
if (nonblock)
@ -513,18 +467,10 @@ int HID_API_EXPORT hid_set_nonblocking(int device, int nonblock)
}
int HID_API_EXPORT hid_send_feature_report(int device, const unsigned char *data, size_t length)
int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
{
struct Device *dev = NULL;
int res;
// Get the handle
if (device < 0 || device >= MAX_DEVICES)
return -1;
if (devices[device].valid == 0)
return -1;
dev = &devices[device];
res = ioctl(dev->device_handle, HIDIOCSFEATURE(length), data);
if (res < 0)
perror("ioctl (SFEATURE)");
@ -532,18 +478,10 @@ int HID_API_EXPORT hid_send_feature_report(int device, const unsigned char *data
return res;
}
int HID_API_EXPORT hid_get_feature_report(int device, unsigned char *data, size_t length)
int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
{
struct Device *dev = NULL;
int res;
// Get the handle
if (device < 0 || device >= MAX_DEVICES)
return -1;
if (devices[device].valid == 0)
return -1;
dev = &devices[device];
res = ioctl(dev->device_handle, HIDIOCGFEATURE(length), data);
if (res < 0)
perror("ioctl (GFEATURE)");
@ -553,97 +491,37 @@ int HID_API_EXPORT hid_get_feature_report(int device, unsigned char *data, size_
}
void HID_API_EXPORT hid_close(int device)
void HID_API_EXPORT hid_close(hid_device *dev)
{
struct Device *dev = NULL;
// Get the handle
if (device < 0 || device >= MAX_DEVICES)
return;
if (devices[device].valid == 0)
return;
dev = &devices[device];
close(dev->device_handle);
dev->valid = 0;
free(dev);
}
int HID_API_EXPORT_CALL hid_get_manufacturer_string(int device, wchar_t *string, size_t maxlen)
int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
struct Device *dev = NULL;
// Get the handle
if (device < 0 || device >= MAX_DEVICES)
return -1;
if (devices[device].valid == 0)
return -1;
dev = &devices[device];
return get_device_string(dev, "manufacturer", string, maxlen);
}
int HID_API_EXPORT_CALL hid_get_product_string(int device, wchar_t *string, size_t maxlen)
int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
struct Device *dev = NULL;
// Get the handle
if (device < 0 || device >= MAX_DEVICES)
return -1;
if (devices[device].valid == 0)
return -1;
dev = &devices[device];
return get_device_string(dev, "product", string, maxlen);
}
int HID_API_EXPORT_CALL hid_get_serial_number_string(int device, wchar_t *string, size_t maxlen)
int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
struct Device *dev = NULL;
// Get the handle
if (device < 0 || device >= MAX_DEVICES)
return -1;
if (devices[device].valid == 0)
return -1;
dev = &devices[device];
return get_device_string(dev, "serial", string, maxlen);
return 0;
}
int HID_API_EXPORT_CALL hid_get_indexed_string(int device, int string_index, wchar_t *string, size_t maxlen)
int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
{
struct Device *dev = NULL;
// Get the handle
if (device < 0 || device >= MAX_DEVICES)
return -1;
if (devices[device].valid == 0)
return -1;
dev = &devices[device];
// TODO:
return -1;
}
HID_API_EXPORT const char * HID_API_CALL hid_error(int device)
HID_API_EXPORT const char * HID_API_CALL hid_error(hid_device *dev)
{
struct Device *dev = NULL;
// Get the handle
if (device < 0 || device >= MAX_DEVICES)
return NULL;
if (devices[device].valid == 0)
return NULL;
dev = &devices[device];
// TODO:
return NULL;
}

View File

@ -12,7 +12,7 @@
#include "hidapi.h"
#include <string.h>
#include <stdlib.h>
#include <limits.h>
class MainWindow : public FXMainWindow {
@ -41,8 +41,8 @@ private:
FXTextField *feature_text;
FXText *input_text;
struct hid_device *devices;
int connected_device;
struct hid_device_info *devices;
hid_device *connected_device;
protected:
MainWindow() {};
@ -82,7 +82,7 @@ MainWindow::MainWindow(FXApp *app)
: FXMainWindow(app, "HIDAPI Test Application", NULL, NULL, DECOR_ALL, 200,100, 425,600)
{
devices = NULL;
connected_device = -1;
connected_device = NULL;
FXVerticalFrame *vf = new FXVerticalFrame(this, LAYOUT_FILL_Y|LAYOUT_FILL_X);
@ -151,7 +151,7 @@ MainWindow::create()
FXMainWindow::create();
show();
struct hid_device *cur_dev;
struct hid_device_info *cur_dev;
// List the Devices
hid_free_enumeration(devices);
@ -186,7 +186,7 @@ MainWindow::create()
long
MainWindow::onConnect(FXObject *sender, FXSelector sel, void *ptr)
{
if (connected_device != -1)
if (connected_device != NULL)
return 1;
FXint cur_item = device_list->getCurrentItem();
@ -195,13 +195,13 @@ MainWindow::onConnect(FXObject *sender, FXSelector sel, void *ptr)
FXListItem *item = device_list->getItem(cur_item);
if (!item)
return -1;
struct hid_device *device_info = (struct hid_device*) item->getData();
struct hid_device_info *device_info = (struct hid_device_info*) item->getData();
if (!device_info)
return -1;
connected_device = hid_open_path(device_info->path);
if (connected_device < 0) {
if (!connected_device) {
FXMessageBox::error(this, MBOX_OK, "Device Error", "Unable To Connect to Device");
return -1;
}
@ -228,7 +228,7 @@ long
MainWindow::onDisconnect(FXObject *sender, FXSelector sel, void *ptr)
{
hid_close(connected_device);
connected_device = -1;
connected_device = NULL;
connected_label->setText("Disconnected");
output_button->disable();
feature_button->disable();
@ -303,6 +303,7 @@ MainWindow::onTimeout(FXObject *sender, FXSelector sel, void *ptr)
}
s += "\n";
input_text->appendText(s);
input_text->setBottomLine(INT_MAX);
}
getApp()->addTimeout(this, ID_TIMER,