From 83764d8cfba2fd3fb3e47a6dd55cd37ac7e70a29 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Wed, 25 Jan 2023 21:32:34 -0600 Subject: [PATCH] Implement the wrapper for Linux in ResourceManager, change IPU to I for HyperX Quadcast S --- .../HyperXQuadcastSController.cpp | 17 +-- .../HyperXQuadcastSControllerDetect.cpp | 6 +- Detector.h | 1 + ResourceManager.cpp | 116 ++++++++++++++++++ 4 files changed, 123 insertions(+), 17 deletions(-) diff --git a/Controllers/HyperXQuadcastController/HyperXQuadcastSController.cpp b/Controllers/HyperXQuadcastController/HyperXQuadcastSController.cpp index ed357581f..855a97611 100644 --- a/Controllers/HyperXQuadcastController/HyperXQuadcastSController.cpp +++ b/Controllers/HyperXQuadcastController/HyperXQuadcastSController.cpp @@ -51,7 +51,6 @@ void HyperXQuadcastSController::SaveColors(std::vector colors, unsigne { using namespace std::chrono_literals; - int res; unsigned int num_color_packets = 0; unsigned int frame = 0; unsigned char color[HXQS_PACKET_SIZE] = {0}; @@ -96,7 +95,7 @@ void HyperXQuadcastSController::SaveColors(std::vector colors, unsigne } std::this_thread::sleep_for(15ms); - res = wrapper.hid_send_feature_report(dev,color,HXQS_PACKET_SIZE); + wrapper.hid_send_feature_report(dev,color,HXQS_PACKET_SIZE); } /*---------------------------------------------------------*\ @@ -131,7 +130,6 @@ void HyperXQuadcastSController::SendDirect(std::vector colors) if(colors.size() != 2) { - LOG_ERROR("[HyperX Quadcast S] Unable to send direct packet, incorrect size: %d", colors.size()); return; } @@ -178,8 +176,7 @@ void HyperXQuadcastSController::SendEOT(uint8_t frame_count) buffer[0x3F] = 0xAA; buffer[0x40] = 0x55; - int result = wrapper.hid_send_feature_report(dev,buffer,HXQS_PACKET_SIZE); - LOG_DEBUG("[HyperX Quadcast S] SendEOT with frame count %02X wrote %d bytes", frame_count, result); + wrapper.hid_send_feature_report(dev,buffer,HXQS_PACKET_SIZE); std::this_thread::sleep_for(15ms); } @@ -196,14 +193,6 @@ void HyperXQuadcastSController::SendToRegister(uint8_t reg, uint8_t param1, uint buffer[0x08] = param1; buffer[0x09] = param2; - int result = wrapper.hid_send_feature_report(dev, buffer, HXQS_PACKET_SIZE); - if(result < 0) - { - LOG_ERROR("[HyperX Quadcast S] SendToRegister failed: %ls", wrapper.hid_error(dev)); - } - else - { - LOG_DEBUG("[HyperX Quadcast S] SendToRegister %02X with P1 %02X P2 %02X wrote %d bytes", reg, param1, param2, result); - } + wrapper.hid_send_feature_report(dev, buffer, HXQS_PACKET_SIZE); std::this_thread::sleep_for(15ms); } diff --git a/Controllers/HyperXQuadcastController/HyperXQuadcastSControllerDetect.cpp b/Controllers/HyperXQuadcastController/HyperXQuadcastSControllerDetect.cpp index 80ebb9905..aba6c84fa 100644 --- a/Controllers/HyperXQuadcastController/HyperXQuadcastSControllerDetect.cpp +++ b/Controllers/HyperXQuadcastController/HyperXQuadcastSControllerDetect.cpp @@ -40,6 +40,6 @@ void DetectHyperXQuadcastSControllers(hidapi_wrapper wrapper, hid_device_info* i ResourceManager::get()->RegisterRGBController(rgb_controller); } -REGISTER_HID_WRAPPED_DETECTOR_IPU("HyperX Quadcast S", DetectHyperXQuadcastSControllers, HYPERX_VID, HYPERX_QS_PID, 0, 0xFF90, 0xFF00); -REGISTER_HID_WRAPPED_DETECTOR_IPU("HyperX Quadcast S", DetectHyperXQuadcastSControllers, HYPERX_HP_VID, HYPERX_QS_PID_HP_1, 0, 0xFF90, 0xFF00); -REGISTER_HID_WRAPPED_DETECTOR_IPU("HyperX Quadcast S", DetectHyperXQuadcastSControllers, HYPERX_HP_VID, HYPERX_QS_PID_HP_2, 0, 0xFF90, 0xFF00); +REGISTER_HID_WRAPPED_DETECTOR_I("HyperX Quadcast S", DetectHyperXQuadcastSControllers, HYPERX_VID, HYPERX_QS_PID, 0);//, 0xFF90, 0xFF00); +REGISTER_HID_WRAPPED_DETECTOR_I("HyperX Quadcast S", DetectHyperXQuadcastSControllers, HYPERX_HP_VID, HYPERX_QS_PID_HP_1, 0);//, 0xFF90, 0xFF00); +REGISTER_HID_WRAPPED_DETECTOR_I("HyperX Quadcast S", DetectHyperXQuadcastSControllers, HYPERX_HP_VID, HYPERX_QS_PID_HP_2, 0);//, 0xFF90, 0xFF00); diff --git a/Detector.h b/Detector.h index 7f1f2e1a5..0aa73b2bd 100644 --- a/Detector.h +++ b/Detector.h @@ -12,6 +12,7 @@ #define REGISTER_HID_DETECTOR_IPU(name, func, vid, pid, interface, page, usage) static HIDDeviceDetector device_detector_obj_##vid##pid##_##interface##_##page##_##usage(name, func, vid, pid, interface, page, usage) #define REGISTER_HID_DETECTOR_P(name, func, vid, pid, page) static HIDDeviceDetector device_detector_obj_##vid##pid##__##page(name, func, vid, pid, HID_INTERFACE_ANY, page, HID_USAGE_ANY) #define REGISTER_HID_DETECTOR_PU(name, func, vid, pid, page, usage) static HIDDeviceDetector device_detector_obj_##vid##pid##__##page##_##usage(name, func, vid, pid, HID_INTERFACE_ANY, page, usage) +#define REGISTER_HID_WRAPPED_DETECTOR_I(name, func, vid, pid, interface) static HIDWrappedDeviceDetector device_detector_obj_##vid##pid##_##interface(name, func, vid, pid, interface, HID_USAGE_PAGE_ANY, HID_USAGE_ANY) #define REGISTER_HID_WRAPPED_DETECTOR_IPU(name, func, vid, pid, interface, page, usage) static HIDWrappedDeviceDetector device_detector_obj_##vid##pid##_##interface##_##page##_##usage(name, func, vid, pid, interface, page, usage) #define REGISTER_DYNAMIC_DETECTOR(name, func) static DynamicDetector device_detector_obj_##func(name, func) #define REGISTER_PRE_DETECTION_HOOK(func) static PreDetectionHook device_detector_obj_##func(func) diff --git a/ResourceManager.cpp b/ResourceManager.cpp index bfa8a58f4..747e2fb4d 100644 --- a/ResourceManager.cpp +++ b/ResourceManager.cpp @@ -1296,6 +1296,122 @@ void ResourceManager::DetectDevicesThreadFunction() hid_free_enumeration(hid_devices); } +#ifdef __linux__ + void* dyn_handle = NULL; + hidapi_wrapper wrapper; + + /*-----------------------------------------*\ + | Load the libhidapi-libusb library | + \*-----------------------------------------*/ + if(!(dyn_handle = dlopen("libhidapi-libusb.so", RTLD_NOW | RTLD_NODELETE | RTLD_DEEPBIND))) + { + return; + } + + wrapper = + { + .dyn_handle = dyn_handle, + .hid_send_feature_report = (hidapi_wrapper_send_feature_report) dlsym(dyn_handle,"hid_send_feature_report"), + .hid_get_feature_report = (hidapi_wrapper_get_feature_report) dlsym(dyn_handle,"hid_get_feature_report"), + .hid_get_serial_num_string = (hidapi_wrapper_get_serial_num_string) dlsym(dyn_handle,"hid_get_serial_number_string"), + .hid_open_path = (hidapi_wrapper_open_path) dlsym(dyn_handle,"hid_open_path"), + .hid_enumerate = (hidapi_wrapper_enumerate) dlsym(dyn_handle,"hid_enumerate"), + .hid_free_enumeration = (hidapi_wrapper_free_enumeration) dlsym(dyn_handle,"hid_free_enumeration"), + .hid_close = (hidapi_wrapper_close) dlsym(dyn_handle,"hid_close"), + .hid_error = (hidapi_wrapper_error) dlsym(dyn_handle,"hid_free_enumeration") + }; + + hid_devices = wrapper.hid_enumerate(0, 0); + + current_hid_device = hid_devices; + + /*-------------------------------------------------*\ + | Iterate through all devices in list and run | + | detectors | + \*-------------------------------------------------*/ + hid_device_count = 0; + + while(current_hid_device) + { + if(LogManager::get()->getLoglevel() >= LL_DEBUG) + { + const char* manu_name = wchar_to_char(current_hid_device->manufacturer_string); + const char* prod_name = wchar_to_char(current_hid_device->product_string); + LOG_DEBUG("[%04X:%04X U=%04X P=0x%04X I=%d] %-25s - %s", current_hid_device->vendor_id, current_hid_device->product_id, current_hid_device->usage, current_hid_device->usage_page, current_hid_device->interface_number, manu_name, prod_name); + } + detection_string = ""; + DetectionProgressChanged(); + + unsigned int addr = (current_hid_device->vendor_id << 16) | current_hid_device->product_id; + + /*-----------------------------------------------------------------------------*\ + | Loop through all available wrapped HID detectors. If all required | + | information matches, run the detector | + \*-----------------------------------------------------------------------------*/ + for(unsigned int hid_detector_idx = 0; hid_detector_idx < hid_wrapped_device_detectors.size() && detection_is_required.load(); hid_detector_idx++) + { + if(( ( hid_wrapped_device_detectors[hid_detector_idx].address == addr ) ) + && ( ( hid_wrapped_device_detectors[hid_detector_idx].usage_page == HID_USAGE_PAGE_ANY ) + || ( hid_wrapped_device_detectors[hid_detector_idx].usage_page == current_hid_device->usage_page ) ) + && ( ( hid_wrapped_device_detectors[hid_detector_idx].usage == HID_USAGE_ANY ) + || ( hid_wrapped_device_detectors[hid_detector_idx].usage == current_hid_device->usage ) ) + && ( ( hid_wrapped_device_detectors[hid_detector_idx].interface == HID_INTERFACE_ANY ) + || ( hid_wrapped_device_detectors[hid_detector_idx].interface == current_hid_device->interface_number ) ) + ) + { + detection_string = hid_wrapped_device_detectors[hid_detector_idx].name.c_str(); + + /*-------------------------------------------------*\ + | Check if this detector is enabled or needs to be | + | added to the settings list | + \*-------------------------------------------------*/ + bool this_device_enabled = true; + if(detector_settings.contains("detectors") && detector_settings["detectors"].contains(detection_string)) + { + this_device_enabled = detector_settings["detectors"][detection_string]; + } + + LOG_DEBUG("[%s] is %s", detection_string, ((this_device_enabled == true) ? "enabled" : "disabled")); + + if(this_device_enabled) + { + DetectionProgressChanged(); + + hid_wrapped_device_detectors[hid_detector_idx].function(wrapper, current_hid_device, hid_wrapped_device_detectors[hid_detector_idx].name); + + if(rgb_controllers_hw.size() != detection_prev_size) + { + LOG_VERBOSE("[%s] successfully added", detection_string); + } + else + { + LOG_INFO("[%s] is not initialized", detection_string); + } + } + } + } + + /*-------------------------------------------------*\ + | Update detection percent | + \*-------------------------------------------------*/ + hid_device_count++; + + percent = (i2c_device_detectors.size() + i2c_pci_device_detectors.size() + hid_device_count) / percent_denominator; + + detection_percent = percent * 100.0f; + + /*-------------------------------------------------*\ + | Move on to the next HID device | + \*-------------------------------------------------*/ + current_hid_device = current_hid_device->next; + } + + /*-------------------------------------------------*\ + | Done using the device list, free it | + \*-------------------------------------------------*/ + wrapper.hid_free_enumeration(hid_devices); +#endif + /*-------------------------------------------------*\ | Detect other devices | \*-------------------------------------------------*/