/* * This is placed into the Public Domain by Jochen Kunz. */ #include #include #include #include #include #include "hidapi.h" #define WSTRLEN 256 #define BUFLEN 16 #define VENDOR_ID 0x046d #define PRODUCT_ID 0xc626 int print_dev_info( hid_device* dev) { wchar_t wstr[ WSTRLEN]; if (hid_get_manufacturer_string( dev, wstr, WSTRLEN) < 0) { printf( "hid_get_manufacturer_string() failed!\n"); } else { printf( "hid_get_manufacturer_string()=%ls\n", wstr); } if (hid_get_product_string( dev, wstr, WSTRLEN) < 0) { printf( "hid_get_product_string() failed!\n"); } else { printf( "hid_get_product_string()=%ls\n", wstr); } if (hid_get_serial_number_string( dev, wstr, WSTRLEN) < 0) { printf( "hid_get_serial_number_string() failed!\n"); } else { printf( "hid_get_serial_number_string()=%ls\n", wstr); } return 0; } int read_3Dev( hid_device* dev) { unsigned char buf[ BUFLEN]; int len; while ((len = hid_read( dev, buf, BUFLEN)) > 0) { /* Print raw data: printf( "hid_read() len=%d\n", len); for (int i = 0; i < len; ++i) { printf( "%02x ", buf[ i]); } printf( "\n"); */ // buf[ 0] == 1 => Translate, 2 => Rotate, 3 => Button event. if ((buf[ 0] == 1 || buf[ 0] == 2) && len == 7) { // Values are in the range -2595..2595. int16_t x_value = buf[ 1] | buf[ 2] << 8; int16_t y_value = buf[ 3] | buf[ 4] << 8; int16_t z_value = buf[ 5] | buf[ 6] << 8; printf( "%s X=%5d Y=%5d Z=%5d\n", buf[ 0] == 1 ? "Translate:" : "Rotate: ", x_value, y_value, z_value); } if (buf[ 0] == 3 && len == 3) { // Is either 0, 1 or 2. uint16_t buttons = buf[ 1] | buf[ 2] << 8; printf( "Button: %x", buttons); // There is no way to distinguish release of button 1 and 2! if (buttons == 0) { printf( " released."); } else { if ((buttons & 1) != 0) { printf( " left"); } if ((buttons & 2) != 0) { printf( " right"); } printf( " pressed."); } printf( "\n"); } } return len; } int poll_nonblocking( hid_device* dev) { if (hid_set_nonblocking( dev, 1) < 0) { return -1; } while (read_3Dev( dev) >= 0) { struct timespec schnarch = { 0, 100000000}; while (nanosleep( &schnarch, &schnarch) < 0) {}; } if (hid_set_nonblocking( dev, 0) < 0) { return -1; } return 0; } int main( int argc, char* argv[]) { uint16_t vendor_id = VENDOR_ID; uint16_t product_id = PRODUCT_ID; if (argc > 1) { vendor_id = strtoul( argv[ 1], NULL, 0); } if (argc > 2) { product_id = strtoul( argv[ 2], NULL, 0); } printf( "vendor_id=0x%04x product_id=0x%04x\n", vendor_id, product_id); if (hid_init() < 0) { fprintf( stderr, "Can't hid_init().\n"); return EXIT_FAILURE; } // Try a list of product IDs. But up to now I know of only one. hid_device* dev = hid_open( vendor_id, product_id, NULL); if (dev == NULL) { fprintf( stderr, "Can't open 3D device.\n"); return EXIT_FAILURE; } if (print_dev_info( dev) < 0 || read_3Dev( dev) < 0) { // if (print_dev_info( dev) < 0 || poll_nonblocking( dev) < 0) { fprintf( stderr, "hid_error()=%ls\n", hid_error( dev)); hid_close( dev); hid_exit(); return EXIT_FAILURE; } hid_close( dev); hid_exit(); return EXIT_SUCCESS; }