Added ergodox hid manager
This commit is contained in:
118
src/ergodox.cpp
Normal file
118
src/ergodox.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
#include "ergodox.hpp"
|
||||
|
||||
|
||||
|
||||
Ergodox::Ergodox(
|
||||
unsigned short vendor_id,
|
||||
unsigned short product_id,
|
||||
unsigned short usage,
|
||||
unsigned short usage_page
|
||||
) :
|
||||
vendor_id(vendor_id),
|
||||
product_id(product_id),
|
||||
usage(usage),
|
||||
usage_page(usage_page),
|
||||
handle(NULL)
|
||||
{
|
||||
hid_init();
|
||||
open();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Initialize Ergodox interface.
|
||||
|
||||
Should be called once at start of execution. Arguments are the USB parameters of the keyboard.
|
||||
|
||||
Returns instance of singleton.
|
||||
*/
|
||||
Ergodox& Ergodox::init(
|
||||
unsigned short vendor_id,
|
||||
unsigned short product_id,
|
||||
unsigned short usage,
|
||||
unsigned short usage_page
|
||||
) {
|
||||
static bool has_been_initialized = false;
|
||||
static Ergodox Instance(
|
||||
vendor_id,
|
||||
product_id,
|
||||
usage,
|
||||
usage_page
|
||||
);
|
||||
|
||||
// This isn't strictly necessary, but there is no reason
|
||||
// to call init() twice.
|
||||
if (has_been_initialized) {
|
||||
has_been_initialized = true;
|
||||
throw std::runtime_error("Ergodox has already been initialized!");
|
||||
}
|
||||
|
||||
return Instance;
|
||||
}
|
||||
|
||||
Ergodox::~Ergodox() {
|
||||
close();
|
||||
hid_exit();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Try to open this keyboard's hid device.
|
||||
Throws a runtime error if device is already open,
|
||||
or if we can't find a device with the given params.
|
||||
*/
|
||||
void Ergodox::open() {
|
||||
if (handle != NULL) {
|
||||
throw std::runtime_error("Device already open");
|
||||
}
|
||||
|
||||
struct hid_device_info *devs, *cur_dev;
|
||||
const char *path_to_open = NULL;
|
||||
|
||||
devs = hid_enumerate(vendor_id, product_id);
|
||||
cur_dev = devs;
|
||||
while (cur_dev) {
|
||||
if (cur_dev->vendor_id == vendor_id &&
|
||||
cur_dev->product_id == product_id &&
|
||||
cur_dev->usage == usage &&
|
||||
cur_dev->usage_page == usage_page
|
||||
) {
|
||||
path_to_open = cur_dev->path;
|
||||
break;
|
||||
}
|
||||
cur_dev = cur_dev->next;
|
||||
}
|
||||
|
||||
if (path_to_open) {
|
||||
handle = hid_open_path(path_to_open);
|
||||
hid_free_enumeration(devs);
|
||||
} else {
|
||||
hid_free_enumeration(devs);
|
||||
throw std::runtime_error("Could not open hid device");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Close hid device if it is open.
|
||||
void Ergodox::close() {
|
||||
if (handle != NULL) {
|
||||
hid_close(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Send data to Ergodox.
|
||||
|
||||
@param data Data to send
|
||||
@param length How many bytes to send
|
||||
@returns Actual number of bytes written, or -1 on error.
|
||||
*/
|
||||
int Ergodox::write(uint8_t* data, size_t length) const {
|
||||
if (handle == NULL) {
|
||||
throw std::runtime_error("Cannot write, device is not open!");
|
||||
}
|
||||
|
||||
return hid_write(handle, data, length);
|
||||
}
|
Reference in New Issue
Block a user