From 7dc6a89c04d210c2233bbf53ef79d327731510a0 Mon Sep 17 00:00:00 2001 From: vhaudiquet Date: Thu, 28 Sep 2023 17:08:28 +0200 Subject: [PATCH] Added mouse DPI interface --- drivers/g-wolves/g-wolves.c | 59 +++++++++++++++++++++++++++++++++++ src/device/device.c | 10 ++++++ src/device/device.h | 6 ++++ src/device/driver_interface.h | 8 +++-- src/ui/panels/mouse-panel.c | 28 ++++++++++++++++- 5 files changed, 108 insertions(+), 3 deletions(-) diff --git a/drivers/g-wolves/g-wolves.c b/drivers/g-wolves/g-wolves.c index f762418..be95f3e 100644 --- a/drivers/g-wolves/g-wolves.c +++ b/drivers/g-wolves/g-wolves.c @@ -74,6 +74,26 @@ uint32_t driver_getkey(void) 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_name(void* handle) { libusb_device* dev = handle; @@ -119,3 +139,42 @@ char* driver_get_image(void* handle) 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; + 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; +} diff --git a/src/device/device.c b/src/device/device.c index c6d6797..9061b96 100644 --- a/src/device/device.c +++ b/src/device/device.c @@ -60,3 +60,13 @@ char* device_get_name(device_t* device) char* (*getname_fn)(void*) = dlsym(device->driver, "driver_get_name"); return getname_fn(device->handle); } + +void* device_handle(device_t* device) +{ + return device->handle; +} + +void* device_driver(device_t* device) +{ + return device->driver; +} diff --git a/src/device/device.h b/src/device/device.h index 37f35f3..a1922b9 100644 --- a/src/device/device.h +++ b/src/device/device.h @@ -2,6 +2,10 @@ #define DEVICE_H #include +#include + +#include "driver_interface.h" + #include "utils/array.h" typedef struct DEVICE device_t; @@ -11,6 +15,8 @@ void device_init(); array_t* device_get_array(); // Handling a single device +void* device_handle(device_t* device); +void* device_driver(device_t* device); device_t* device_register(void* driver, void* handle); char* device_get_image(device_t* device); char* device_get_name(device_t* device); diff --git a/src/device/driver_interface.h b/src/device/driver_interface.h index 11bdbc4..dd3847c 100644 --- a/src/device/driver_interface.h +++ b/src/device/driver_interface.h @@ -1,6 +1,9 @@ #ifndef DRIVER_INTERFACE_H #define DRIVER_INTERFACE_H +#include +#include + typedef enum DEVICE_CAPACITY { DEVICE_CAPACITY_MOUSE, @@ -15,6 +18,7 @@ char* driver_get_name(void* handle); // Returns peripheral name char* driver_get_image(void* handle); // Returns peripheral image /* Mouse drivers */ +#define MAX_DPI_LEVELS 10 struct MOUSE_DPI_LEVELS { unsigned int max_level_count; @@ -29,8 +33,8 @@ struct MOUSE_DPI_LEVELS unsigned char r; unsigned char g; unsigned char b; - } level[]; + } level[MAX_DPI_LEVELS]; }; -struct MOUSE_DPI_LEVELS driver_mouse_dpi_get(void* handle); +int driver_mouse_dpi_get(void* handle, struct MOUSE_DPI_LEVELS* output); #endif \ No newline at end of file diff --git a/src/ui/panels/mouse-panel.c b/src/ui/panels/mouse-panel.c index 67b0008..0bf2bea 100644 --- a/src/ui/panels/mouse-panel.c +++ b/src/ui/panels/mouse-panel.c @@ -39,8 +39,34 @@ mouse_panel_new(void) void mouse_panel_set_device(MousePanel* self, device_t* device) { + // Set device image char* image = device_get_image(device); gtk_image_set_from_file(self->mouse_image, image); - gtk_label_set_label(self->mouse_name, device_get_name(device)); free(image); + + // Set device name + gtk_label_set_label(self->mouse_name, device_get_name(device)); + + // Set mouse dpi + struct MOUSE_DPI_LEVELS dpi; + int (*driver_mouse_dpi_get)(void*, void*) = dlsym(device_driver(device), "driver_mouse_dpi_get"); + int dpi_res = driver_mouse_dpi_get(device_handle(device), &dpi); + if(!dpi_res) + { + // Set dpi list + for(size_t i = 0; i < dpi.level_count; i++) + { + AdwPreferencesRow* row = ADW_PREFERENCES_ROW(adw_preferences_row_new()); + + // Convert dpi int to string + char dpi_str[10]; + sprintf(dpi_str, "%u", dpi.level[i].dpi_x); + + GtkLabel* label = GTK_LABEL(gtk_label_new(dpi_str)); + gtk_widget_add_css_class(GTK_WIDGET(label), "heading"); + gtk_list_box_row_set_child(GTK_LIST_BOX_ROW(row), GTK_WIDGET(label)); + + adw_preferences_group_add(self->dpi_preference_group, GTK_WIDGET(row)); + } + } }