#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; } // Instance is a static function variable, // and will be deleted at end of program. 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); }