Gnome input devices manager
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
ginput/drivers/g-wolves/g-wolves.c

185 lines
4.8 KiB

#include "g-wolves.h"
static int send_command(libusb_device_handle* hand, uint8_t command, uint8_t size, void* report, bool wireless)
{
report_header_t* head = report;
head->report_size = size;
head->command = command;
if(wireless)
head->wireless = 0x1;
// Send command
int res = libusb_control_transfer(hand,
0x21, // request type
0x09, // request (SET_REPORT)
0x300, // wValue (FEATURE << 8 | REPORT(0))
0x2, // wIndex = 0x2 : interface
report,
REPORT_MAX_SIZE, // wLength = 64
0 /* timeout*/);
if(res <= 0) return res;
// Wait for mouse if necessary
if(wireless)
usleep(100000);
// Get response report
res = libusb_control_transfer(hand,
0xa1, // request type
0x01, // request (GET_REPORT)
0x300, // wValue (FEATURE << 8 | REPORT(0))
0x2, // wIndex = 0x2 : interface
report,
REPORT_MAX_SIZE, // wLength = 64
0);
return res;
}
void driver_init(void) {}
uint32_t driver_getkey(void)
{
static int count = 0;
count++;
// Register ALL G-Wolves compatible devices
uint16_t id = 0;
switch(count)
{
case 1:
id = HTX_4K_PRODUCT_ID_WIRED;
break;
case 2:
id = HTX_4K_PRODUCT_ID_WIRELESS;
break;
case 3:
id = HTS_PLUS_4K_PRODUCT_ID_WIRED;
break;
case 4:
id = HTS_PLUS_4K_PRODUCT_ID_WIRELESS;
break;
case 5:
id = HSK_PRO_ACE_PRODUCT_ID_WIRED;
break;
case 6:
id = HSK_PRO_ACE_PRODUCT_ID_WIRELESS;
break;
default:
id = 0;
}
if(id == 0) return 0;
return (VENDOR_ID << 16) | id;
}
device_capacity_t driver_get_capacity(void* handle)
{
libusb_device* dev = handle;
struct libusb_device_descriptor desc;
libusb_get_device_descriptor(dev, &desc);
uint8_t wireless = 0;
switch(desc.idProduct)
{
case HTX_4K_PRODUCT_ID_WIRELESS:
case HTS_PLUS_4K_PRODUCT_ID_WIRELESS:
case HSK_PRO_ACE_PRODUCT_ID_WIRELESS:
wireless = 1;
break;
}
return DEVICE_CAPACITY_MOUSE | wireless;
}
char* driver_get_manufacturer(void* handle)
{
return MANUFACTURER_NAME;
}
char* driver_get_name(void* handle)
{
libusb_device* dev = handle;
struct libusb_device_descriptor desc;
libusb_get_device_descriptor(dev, &desc);
switch(desc.idProduct)
{
case HTX_4K_PRODUCT_ID_WIRED:
case HTX_4K_PRODUCT_ID_WIRELESS:
return HTX_4K_PRODUCT_NAME;
case HTS_PLUS_4K_PRODUCT_ID_WIRED:
case HTS_PLUS_4K_PRODUCT_ID_WIRELESS:
return HTS_PLUS_4K_PRODUCT_NAME;
case HSK_PRO_ACE_PRODUCT_ID_WIRED:
case HSK_PRO_ACE_PRODUCT_ID_WIRELESS:
return HSK_PRO_ACE_PRODUCT_NAME;
default:
return "Unknown G-Wolves mice";
}
}
char* driver_get_image(void* handle)
{
libusb_device* dev = handle;
struct libusb_device_descriptor desc;
libusb_get_device_descriptor(dev, &desc);
switch(desc.idProduct)
{
case HTX_4K_PRODUCT_ID_WIRED:
case HTX_4K_PRODUCT_ID_WIRELESS:
return HTX_IMAGE;
case HTS_PLUS_4K_PRODUCT_ID_WIRED:
case HTS_PLUS_4K_PRODUCT_ID_WIRELESS:
return HTS_PLUS_IMAGE;
case HSK_PRO_ACE_PRODUCT_ID_WIRED:
case HSK_PRO_ACE_PRODUCT_ID_WIRELESS:
return HSK_PRO_IMAGE;
default:
return "";
}
}
int driver_mouse_dpi_get(void* handle, struct MOUSE_DPI_LEVELS* output)
{
libusb_device* dev = handle;
// Prepare usb device for transfer
libusb_device_handle* hand;
int openres = libusb_open(dev, &hand);
if(openres) return -1;
libusb_detach_kernel_driver(hand, 0x2);
// Send command
struct REPORT_DPI_SETTINGS report = {0};
bool wireless = false;
if(driver_get_capacity(handle) & DEVICE_CAPACITY_WIRELESS) wireless = true;
int res = send_command(hand, COMMAND_DPI_SETTINGS, REPORT_DPI_SETTINGS_SIZE, &report, wireless);
if(res <= 0) return -1;
// Format 'output' packet
output->max_level_count = 5;
output->level_count = report.level_count;
output->level_current = report.level_current - 1;
output->led_available = true;
output->xy_available = false;
for(size_t i = 0; i < report.level_count; i++)
{
output->level[i].dpi_x = report.levels[i].dpi_x_high << 8 | report.levels[i].dpi_x_low;
output->level[i].dpi_y = report.levels[i].dpi_y_high << 8 | report.levels[i].dpi_y_low;
output->level[i].r = report.levels[i].led_r;
output->level[i].g = report.levels[i].led_g;
output->level[i].b = report.levels[i].led_b;
}
libusb_attach_kernel_driver(hand, 0x2);
libusb_close(hand);
return 0;
}