From ec8cdf1e2685c9fcae645bd8158f131e1f1056b9 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Thu, 9 Jan 2020 18:57:33 -0600 Subject: [PATCH] Bring in USB HID device support with hidapi and add support for two new HID devices - MSI/SteelSeries 3-zone laptop keyboard and Thermaltake TtEsports Poseidon Z RGB keyboard --- .../MSI3ZoneController/MSI3ZoneController.cpp | 78 ++++ .../MSI3ZoneController/MSI3ZoneController.h | 30 ++ .../MSI3ZoneControllerDetect.cpp | 36 ++ .../PoseidonZRGBController.cpp | 173 ++++++++ .../PoseidonZRGBController.h | 38 ++ .../PoseidonZRGBControllerDetect.cpp | 36 ++ OpenRGB.cpp | 4 + OpenRGB.pro | 24 +- RGBController/RGBController_MSI3Zone.cpp | 95 +++++ RGBController/RGBController_MSI3Zone.h | 28 ++ RGBController/RGBController_PoseidonZRGB.cpp | 58 +++ RGBController/RGBController_PoseidonZRGB.h | 28 ++ dependencies/hidapi-win/x64/hidapi.dll | Bin 0 -> 18432 bytes dependencies/hidapi-win/x64/hidapi.lib | Bin 0 -> 5186 bytes dependencies/hidapi-win/x86/hidapi.dll | Bin 0 -> 14336 bytes dependencies/hidapi-win/x86/hidapi.lib | Bin 0 -> 5270 bytes dependencies/hidapi/hidapi.h | 395 ++++++++++++++++++ 17 files changed, 1019 insertions(+), 4 deletions(-) create mode 100644 Controllers/MSI3ZoneController/MSI3ZoneController.cpp create mode 100644 Controllers/MSI3ZoneController/MSI3ZoneController.h create mode 100644 Controllers/MSI3ZoneController/MSI3ZoneControllerDetect.cpp create mode 100644 Controllers/PoseidonZRGBController/PoseidonZRGBController.cpp create mode 100644 Controllers/PoseidonZRGBController/PoseidonZRGBController.h create mode 100644 Controllers/PoseidonZRGBController/PoseidonZRGBControllerDetect.cpp create mode 100644 RGBController/RGBController_MSI3Zone.cpp create mode 100644 RGBController/RGBController_MSI3Zone.h create mode 100644 RGBController/RGBController_PoseidonZRGB.cpp create mode 100644 RGBController/RGBController_PoseidonZRGB.h create mode 100644 dependencies/hidapi-win/x64/hidapi.dll create mode 100644 dependencies/hidapi-win/x64/hidapi.lib create mode 100644 dependencies/hidapi-win/x86/hidapi.dll create mode 100644 dependencies/hidapi-win/x86/hidapi.lib create mode 100644 dependencies/hidapi/hidapi.h diff --git a/Controllers/MSI3ZoneController/MSI3ZoneController.cpp b/Controllers/MSI3ZoneController/MSI3ZoneController.cpp new file mode 100644 index 000000000..6ea7e199e --- /dev/null +++ b/Controllers/MSI3ZoneController/MSI3ZoneController.cpp @@ -0,0 +1,78 @@ +/*-----------------------------------------*\ +| MSI3ZoneController.cpp | +| | +| Driver for MSI/Steelseries 3-Zone | +| Keyboard lighting controller | +| | +| Adam Honse (CalcProgrammer1) 12/25/2019 | +\*-----------------------------------------*/ + +#include "MSI3ZoneController.h" + +MSI3ZoneController::MSI3ZoneController(hid_device* dev_handle) +{ + dev = dev_handle; + + //strcpy(device_name, "MSI 3-Zone Keyboard"); +} + +MSI3ZoneController::~MSI3ZoneController() +{ + +} + +char* MSI3ZoneController::GetDeviceName() +{ + return device_name; +} + +void MSI3ZoneController::SetLEDs(std::vector colors) +{ + //Shout out to bparker06 for reverse engineering the MSI keyboard USB protocol! + // https://github.com/bparker06/msi-keyboard/blob/master/keyboard.cpp for original implementation + unsigned char buf[8] = { 0 }; + + buf[0] = 1; + buf[1] = 2; + buf[2] = 64; + buf[3] = 1; + buf[4] = RGBGetRValue(colors[0]); + buf[5] = RGBGetGValue(colors[0]); + buf[6] = RGBGetBValue(colors[0]); + buf[7] = 236; + + hid_send_feature_report(dev, buf, 8); + + buf[3] = 2; + buf[4] = RGBGetRValue(colors[1]); + buf[5] = RGBGetGValue(colors[1]); + buf[6] = RGBGetBValue(colors[1]); + + hid_send_feature_report(dev, buf, 8); + + buf[3] = 3; + buf[4] = RGBGetRValue(colors[2]); + buf[5] = RGBGetGValue(colors[2]); + buf[6] = RGBGetBValue(colors[2]); + + hid_send_feature_report(dev, buf, 8); + + buf[3] = 4; + buf[4] = RGBGetRValue(colors[3]); + buf[5] = RGBGetGValue(colors[3]); + buf[6] = RGBGetBValue(colors[3]); + + hid_send_feature_report(dev, buf, 8); + + buf[3] = 5; + + hid_send_feature_report(dev, buf, 8); + + buf[3] = 6; + + hid_send_feature_report(dev, buf, 8); + + buf[3] = 7; + + hid_send_feature_report(dev, buf, 8); +} diff --git a/Controllers/MSI3ZoneController/MSI3ZoneController.h b/Controllers/MSI3ZoneController/MSI3ZoneController.h new file mode 100644 index 000000000..12eb81e6e --- /dev/null +++ b/Controllers/MSI3ZoneController/MSI3ZoneController.h @@ -0,0 +1,30 @@ +/*-----------------------------------------*\ +| MSI3ZoneController.h | +| | +| Definitions and types for MSI/Steelseries| +| 3-Zone Keyboard lighting controller | +| | +| Adam Honse (CalcProgrammer1) 12/25/2019 | +\*-----------------------------------------*/ + +#include "RGBController.h" + +#include +#include "hidapi.h" + +#pragma once + +class MSI3ZoneController +{ +public: + MSI3ZoneController(hid_device* dev_handle); + ~MSI3ZoneController(); + + char* GetDeviceName(); + + void SetLEDs(std::vector colors); + +private: + char device_name[32]; + hid_device* dev; +}; diff --git a/Controllers/MSI3ZoneController/MSI3ZoneControllerDetect.cpp b/Controllers/MSI3ZoneController/MSI3ZoneControllerDetect.cpp new file mode 100644 index 000000000..b031f0b7d --- /dev/null +++ b/Controllers/MSI3ZoneController/MSI3ZoneControllerDetect.cpp @@ -0,0 +1,36 @@ +#include "MSI3ZoneController.h" +#include "RGBController.h" +#include "RGBController_MSI3Zone.h" +#include +#include "hidapi.h" + +#define MSI_3_ZONE_KEYBOARD_VID 0x1770 +#define MSI_3_ZONE_KEYBOARD_PID 0xFF00 + +/******************************************************************************************\ +* * +* DetectMSI3ZoneControllers * +* * +* Tests the USB address to see if an MSI/SteelSeries 3-zone Keyboard controller * +* exists there. * +* * +\******************************************************************************************/ + +void DetectMSI3ZoneControllers(std::vector& rgb_controllers) +{ + hid_device* dev; + + //Look for MSI/Steelseries 3-zone Keyboard + hid_init(); + + dev = hid_open(MSI_3_ZONE_KEYBOARD_VID, MSI_3_ZONE_KEYBOARD_PID, 0); + + if( dev ) + { + MSI3ZoneController* controller = new MSI3ZoneController(dev); + + RGBController_MSI3Zone* rgb_controller = new RGBController_MSI3Zone(controller); + + rgb_controllers.push_back(rgb_controller); + } +} diff --git a/Controllers/PoseidonZRGBController/PoseidonZRGBController.cpp b/Controllers/PoseidonZRGBController/PoseidonZRGBController.cpp new file mode 100644 index 000000000..17cdf8b73 --- /dev/null +++ b/Controllers/PoseidonZRGBController/PoseidonZRGBController.cpp @@ -0,0 +1,173 @@ +/*-----------------------------------------*\ +| PoseidonZRGBController.cpp | +| | +| Driver for Thermaltake Poseidon Z RGB | +| Keyboard lighting controller | +| | +| Adam Honse (CalcProgrammer1) 12/25/2019 | +\*-----------------------------------------*/ + +#include "PoseidonZRGBController.h" + +#ifdef WIN32 +#include +#else +#include + +static void Sleep(unsigned int milliseconds) +{ + usleep(1000 * milliseconds); +} +#endif + +static unsigned int keys[] = {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, + 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, + 36, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, 62, 63, 64, + 65, 66, 67, 68, 70, 71, 72, 73, 74, 75, 76, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 102, 103, 104, 105, + 106, 108, 109, 111, 112, 114, 115, 117, 118, 119, 120, + 124, 128, 129 }; + +PoseidonZRGBController::PoseidonZRGBController(hid_device* dev_handle) +{ + dev = dev_handle; +} + +PoseidonZRGBController::~PoseidonZRGBController() +{ + +} + +char* PoseidonZRGBController::GetDeviceName() +{ + return device_name; +} + +void PoseidonZRGBController::SetLEDsDirect(std::vector colors) +{ + unsigned char red_grn_buf[264]; + unsigned char blu_buf[264]; + + for(int i = 0; i < 264; i++) + { + red_grn_buf[i] = 0x00; + blu_buf[i] = 0x00; + } + + red_grn_buf[0] = POSEIDONZ_START; + red_grn_buf[1] = POSEIDONZ_LED_CMD; + red_grn_buf[2] = POSEIDONZ_PROFILE; + red_grn_buf[3] = POSEIDONZ_RED_GRN_CH; + red_grn_buf[4] = 0x00; + red_grn_buf[5] = 0x00; + red_grn_buf[6] = 0x00; + red_grn_buf[7] = 0x00; + + blu_buf[0] = POSEIDONZ_START; + blu_buf[1] = POSEIDONZ_LED_CMD; + blu_buf[2] = POSEIDONZ_PROFILE; + blu_buf[3] = POSEIDONZ_BLU_CH; + blu_buf[4] = 0x00; + blu_buf[5] = 0x00; + blu_buf[6] = 0x00; + blu_buf[7] = 0x00; + + for(int i = 0; i < 104; i++) + { + red_grn_buf[keys[i] ] = RGBGetRValue(colors[i]); + red_grn_buf[keys[i] + 128] = RGBGetGValue(colors[i]); + blu_buf[ keys[i] ] = RGBGetBValue(colors[i]); + } + + hid_send_feature_report(dev, red_grn_buf, 264); + + Sleep(1); + + hid_send_feature_report(dev, blu_buf, 264); + +} + +void PoseidonZRGBController::SetLEDs(std::vector colors) +{ + unsigned char buf[264] = {0}; + + //Send Red Packet + for(int i = 0; i < 264; i++) + { + buf[i] = 0xFF; + } + + buf[0] = 0x07; + buf[1] = 0x09; + buf[2] = 0x01; + buf[3] = 0x01; + + for(int i = 0; i < 104; i++) + { + buf[keys[i]] = RGBGetRValue(colors[i]); + } + + hid_send_feature_report(dev, buf, 264); + + Sleep(10); + + //Send Green Packet + for(int i = 0; i < 264; i++) + { + buf[i] = 0x00; + } + + buf[0] = 0x07; + buf[1] = 0x09; + buf[2] = 0x01; + buf[3] = 0x02; + + buf[8] = 0xFF; + + for(int i = 0; i < 104; i++) + { + buf[keys[i]] = RGBGetGValue(colors[i]); + } + + hid_send_feature_report(dev, buf, 264); + + Sleep(10); + + //Send Blue Packet + for(int i = 0; i < 264; i++) + { + buf[i] = 0x11; + } + + buf[0] = 0x07; + buf[1] = 0x09; + buf[2] = 0x01; + buf[3] = 0x03; + + for(int i = 0; i < 104; i++) + { + buf[keys[i]] = RGBGetBValue(colors[i]); + } + + hid_send_feature_report(dev, buf, 264); + + Sleep(10); + + //Send Update Packet + for(int i = 0; i < 264; i++) + { + buf[i] = 0x00; + } + + buf[0] = 0x07; + buf[1] = 0x02; + buf[2] = 0x01; + buf[8] = 0x01; //Preset to save + buf[13] = 0x04; //Brightness? + buf[16] = 0x08; + buf[22] = 0x03; + + hid_send_feature_report(dev, buf, 264); +} diff --git a/Controllers/PoseidonZRGBController/PoseidonZRGBController.h b/Controllers/PoseidonZRGBController/PoseidonZRGBController.h new file mode 100644 index 000000000..f0e0773ae --- /dev/null +++ b/Controllers/PoseidonZRGBController/PoseidonZRGBController.h @@ -0,0 +1,38 @@ +/*-----------------------------------------*\ +| PoseidonZRGBController.h | +| | +| Definitions and types for Thermaltake | +| Poseidon Z RGB Keyboard lighting | +| controller | +| | +| Adam Honse (CalcProgrammer1) 12/25/2019 | +\*-----------------------------------------*/ + +#include "RGBController.h" + +#include +#include "hidapi.h" + +#pragma once + +#define POSEIDONZ_START 0x07 +#define POSEIDONZ_PROFILE 0x01 +#define POSEIDONZ_LED_CMD 0x0E +#define POSEIDONZ_RED_GRN_CH 0x01 +#define POSEIDONZ_BLU_CH 0x02 + +class PoseidonZRGBController +{ +public: + PoseidonZRGBController(hid_device* dev_handle); + ~PoseidonZRGBController(); + + char* GetDeviceName(); + + void SetLEDsDirect(std::vector colors); + void SetLEDs(std::vector colors); + +private: + char device_name[32]; + hid_device* dev; +}; diff --git a/Controllers/PoseidonZRGBController/PoseidonZRGBControllerDetect.cpp b/Controllers/PoseidonZRGBController/PoseidonZRGBControllerDetect.cpp new file mode 100644 index 000000000..60ee79232 --- /dev/null +++ b/Controllers/PoseidonZRGBController/PoseidonZRGBControllerDetect.cpp @@ -0,0 +1,36 @@ +#include "PoseidonZRGBController.h" +#include "RGBController.h" +#include "RGBController_PoseidonZRGB.h" +#include +#include "hidapi.h" + +#define TT_POSEIDON_Z_RGB_VID 0x264A +#define TT_POSEIDON_Z_RGB_PID 0x3006 + +/******************************************************************************************\ +* * +* DetectPoseidonZRGBControllers * +* * +* Tests the USB address to see if a Thermaltake Poseidon Z RGB Keyboard controller * +* exists there. * +* * +\******************************************************************************************/ + +void DetectPoseidonZRGBControllers(std::vector& rgb_controllers) +{ + hid_device* dev; + + //Look for Thermaltake Poseidon Z RGB Keyboard + hid_init(); + + dev = hid_open(TT_POSEIDON_Z_RGB_VID, TT_POSEIDON_Z_RGB_PID, 0); + + if( dev ) + { + PoseidonZRGBController* controller = new PoseidonZRGBController(dev); + + RGBController_PoseidonZRGB* rgb_controller = new RGBController_PoseidonZRGB(controller); + + rgb_controllers.push_back(rgb_controller); + } +} diff --git a/OpenRGB.cpp b/OpenRGB.cpp index 47b0738a6..282a3c944 100644 --- a/OpenRGB.cpp +++ b/OpenRGB.cpp @@ -332,6 +332,8 @@ void DetectRazerChromaSDKControllers(std::vector& rgb_controller void DetectE131Controllers(std::vector &rgb_controllers); void DetectAMDWraithPrismControllers(std::vector& rgb_controllers); void DetectAorusGPUControllers(std::vector &rgb_controllers); +void DetectMSI3ZoneControllers(std::vector& rgb_controllers); +void DetectPoseidonZRGBControllers(std::vector& rgb_controllers); /******************************************************************************************\ * * @@ -358,6 +360,8 @@ void DetectRGBControllers(void) DetectHuePlusControllers(rgb_controllers); DetectAMDWraithPrismControllers(rgb_controllers); + DetectMSI3ZoneControllers(rgb_controllers); + DetectPoseidonZRGBControllers(rgb_controllers); DetectE131Controllers(rgb_controllers); diff --git a/OpenRGB.pro b/OpenRGB.pro index c8331b146..7aa1fdf30 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -19,14 +19,15 @@ INCLUDEPATH += \ Controllers/HuePlusController/ \ Controllers/HyperXController/ \ Controllers/LEDStripController/ \ + Controllers/MSI3ZoneController/ \ Controllers/PatriotViperController/ \ Controllers/PolychromeController/ \ + Controllers/PoseidonZRGBController/ \ Controllers/RGBFusionController/ \ RGBController/ \ qt/ SOURCES += \ - RGBController/RGBController.cpp \ dependencies/libe131/src/e131.c \ main.cpp \ OpenRGB.cpp \ @@ -56,12 +57,17 @@ SOURCES += \ Controllers/HyperXController/HyperXControllerDetect.cpp \ Controllers/LEDStripController/LEDStripController.cpp \ Controllers/LEDStripController/LEDStripControllerDetect.cpp \ + Controllers/MSI3ZoneController/MSI3ZoneController.cpp \ + Controllers/MSI3ZoneController/MSI3ZoneControllerDetect.cpp \ Controllers/PatriotViperController/PatriotViperController.cpp \ Controllers/PatriotViperController/PatriotViperControllerDetect.cpp \ Controllers/PolychromeController/PolychromeController.cpp \ Controllers/PolychromeController/PolychromeControllerDetect.cpp \ + Controllers/PoseidonZRGBController/PoseidonZRGBController.cpp \ + Controllers/PoseidonZRGBController/PoseidonZRGBControllerDetect.cpp \ Controllers/RGBFusionController/RGBFusionController.cpp \ Controllers/RGBFusionController/RGBFusionControllerDetect.cpp \ + RGBController/RGBController.cpp \ RGBController/E131ControllerDetect.cpp \ RGBController/RGBController_AMDWraithPrism.cpp \ RGBController/RGBController_Aura.cpp \ @@ -72,17 +78,19 @@ SOURCES += \ RGBController/RGBController_HyperX.cpp \ RGBController/RGBController_E131.cpp \ RGBController/RGBController_LEDStrip.cpp \ + RGBController/RGBController_MSI3Zone.cpp \ RGBController/RGBController_PatriotViper.cpp \ RGBController/RGBController_Polychrome.cpp \ + RGBController/RGBController_PoseidonZRGB.cpp \ RGBController/RGBController_RGBFusion.cpp HEADERS += \ - Controllers/RGBFusionController/RGBFusionController.h \ qt/OpenRGBDeviceInfoPage.h \ qt/OpenRGBDevicePage.h \ qt/OpenRGBDialog.h \ i2c_smbus/i2c_smbus.h \ i2c_tools/i2c_tools.h \ + hidapi/hidapi.h \ net_port/net_port.h \ qt/OpenRGBDialog2.h \ qt/OpenRGBSystemInfoPage.h \ @@ -96,8 +104,10 @@ HEADERS += \ Controllers/HuePlusController/HuePlusController.h \ Controllers/HyperXController/HyperXController.h \ Controllers/LEDStripController/LEDStripController.h \ + Controllers/MSI3ZoneController/MSI3ZoneController.h \ Controllers/PatriotViperController/PatriotViperController.h \ Controllers/PolychromeController/PolychromeController.h \ + Controllers/PoseidonZRGBController/PoseidonZRGBController.h \ Controllers/RGBFusionController/RGBFusionController.h \ RGBController/RGBController.h \ RGBController/RGBController_AMDWraithPrism.h \ @@ -108,8 +118,11 @@ HEADERS += \ RGBController/RGBController_Hue2.h \ RGBController/RGBController_HuePlus.h \ RGBController/RGBController_HyperX.h \ + RGBController/RGBController_LEDStrip.h \ + RGBController/RGBController_MSI3Zone.h \ RGBController/RGBController_PatriotViper.h \ RGBController/RGBController_Polychrome.h \ + RGBController/RGBController_PoseidonZRGB.h \ RGBController/RGBController_RGBFusion.h RESOURCES += \ @@ -129,6 +142,7 @@ win32:INCLUDEPATH += \ dependencies/inpout32_1501/Win32/ \ dependencies/razer-chroma-2.9.0/inc \ dependencies/libusb-1.0.22/include \ + dependencies/hidapi \ wmi/ \ win32:SOURCES += \ @@ -154,7 +168,8 @@ win32:HEADERS += \ win32:LIBS += \ -lws2_32 \ -L"$$PWD/dependencies/inpout32_1501/Win32/" -linpout32 \ - -L"$$PWD/dependencies/libusb-1.0.22/MS32/dll" -llibusb-1.0 + -L"$$PWD/dependencies/libusb-1.0.22/MS32/dll" -llibusb-1.0 \ + -L"$$PWD/dependencies/hidapi-win/x86/" -lhidapi win32:DEFINES -= \ UNICODE @@ -175,7 +190,8 @@ unix:HEADERS += \ i2c_smbus/i2c_smbus_linux.h \ unix:LIBS += \ - -lusb-1.0 + -lusb-1.0 \ + -lhidapi unix:SOURCES += \ i2c_smbus/i2c_smbus_linux.cpp \ diff --git a/RGBController/RGBController_MSI3Zone.cpp b/RGBController/RGBController_MSI3Zone.cpp new file mode 100644 index 000000000..906fa60cd --- /dev/null +++ b/RGBController/RGBController_MSI3Zone.cpp @@ -0,0 +1,95 @@ +/*-----------------------------------------*\ +| RGBController_MSI3Zone.cpp | +| | +| Generic RGB Interface for MSI/Steelseries| +| 3-Zone Keyboard | +| | +| Adam Honse (CalcProgrammer1) 12/25/2019 | +\*-----------------------------------------*/ + +#include "RGBController_MSI3Zone.h" + +RGBController_MSI3Zone::RGBController_MSI3Zone(MSI3ZoneController* msi_ptr) +{ + msi = msi_ptr; + + name = "MSI 3-Zone Keyboard"; + type = DEVICE_TYPE_KEYBOARD; + + mode led_mode; + led_mode.name = "Custom"; + modes.push_back(led_mode); + + led left_led; + left_led.name = "Keyboard Left"; + leds.push_back(left_led); + colors.push_back(0x00000000); + + led mid_led; + mid_led.name = "Keyboard Middle"; + leds.push_back(mid_led); + colors.push_back(0x00000000); + + led right_led; + right_led.name = "Keyboard Right"; + leds.push_back(right_led); + colors.push_back(0x00000000); + + zone keyboard_zone; + keyboard_zone.name = "Keyboard"; + keyboard_zone.type = ZONE_TYPE_LINEAR; + std::vector keyboard_zone_map; + keyboard_zone_map.push_back(0); + keyboard_zone_map.push_back(1); + keyboard_zone_map.push_back(2); + keyboard_zone.map.push_back(keyboard_zone_map); + zones.push_back(keyboard_zone); + + led aux_led; + aux_led.name = "Aux"; + leds.push_back(aux_led); + colors.push_back(0x00000000); + + zone aux_zone; + aux_zone.name = "Aux"; + aux_zone.type = ZONE_TYPE_SINGLE; + std::vector aux_zone_map; + aux_zone_map.push_back(3); + aux_zone.map.push_back(aux_zone_map); + zones.push_back(aux_zone); +} + +RGBController_MSI3Zone::~RGBController_MSI3Zone() +{ + +} + +int RGBController_MSI3Zone::GetMode() +{ + return 0; +} + +void RGBController_MSI3Zone::SetMode(int mode) +{ + +} + +void RGBController_MSI3Zone::SetCustomMode() +{ + +} + +void RGBController_MSI3Zone::UpdateLEDs() +{ + msi->SetLEDs(colors); +} + +void RGBController_MSI3Zone::UpdateZoneLEDs(int zone) +{ + msi->SetLEDs(colors); +} + +void RGBController_MSI3Zone::UpdateSingleLED(int led) +{ + msi->SetLEDs(colors); +} \ No newline at end of file diff --git a/RGBController/RGBController_MSI3Zone.h b/RGBController/RGBController_MSI3Zone.h new file mode 100644 index 000000000..871ad0ec8 --- /dev/null +++ b/RGBController/RGBController_MSI3Zone.h @@ -0,0 +1,28 @@ +/*-----------------------------------------*\ +| RGBController_MSI3Zone.h | +| | +| Generic RGB Interface for MSI/Steelseries| +| 3-Zone Keyboard | +| | +| Adam Honse (CalcProgrammer1) 12/25/2019 | +\*-----------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "MSI3ZoneController.h" + +class RGBController_MSI3Zone : public RGBController +{ +public: + RGBController_MSI3Zone(MSI3ZoneController* msi_ptr); + ~RGBController_MSI3Zone(); + int GetMode(); + void SetMode(int mode); + void SetCustomMode(); + void UpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + +private: + MSI3ZoneController* msi; +}; \ No newline at end of file diff --git a/RGBController/RGBController_PoseidonZRGB.cpp b/RGBController/RGBController_PoseidonZRGB.cpp new file mode 100644 index 000000000..07294d4be --- /dev/null +++ b/RGBController/RGBController_PoseidonZRGB.cpp @@ -0,0 +1,58 @@ +/*-----------------------------------------*\ +| RGBController_PoseidonZRGB.cpp | +| | +| Generic RGB Interface for Thermaltake | +| Poseidon Z RGB Keyboard | +| | +| Adam Honse (CalcProgrammer1) 12/25/2019 | +\*-----------------------------------------*/ + +#include "RGBController_PoseidonZRGB.h" + +RGBController_PoseidonZRGB::RGBController_PoseidonZRGB(PoseidonZRGBController* poseidon_ptr) +{ + poseidon = poseidon_ptr; + + name = "Thermaltake Poseidon Z RGB"; + type = DEVICE_TYPE_KEYBOARD; + + for(int i = 0; i < 104; i++) + { + colors.push_back(0x00000000); + } +} + +RGBController_PoseidonZRGB::~RGBController_PoseidonZRGB() +{ + +} + +int RGBController_PoseidonZRGB::GetMode() +{ + return 0; +} + +void RGBController_PoseidonZRGB::SetMode(int mode) +{ + +} + +void RGBController_PoseidonZRGB::SetCustomMode() +{ + +} + +void RGBController_PoseidonZRGB::UpdateLEDs() +{ + poseidon->SetLEDs(colors); +} + +void RGBController_PoseidonZRGB::UpdateZoneLEDs(int zone) +{ + poseidon->SetLEDs(colors); +} + +void RGBController_PoseidonZRGB::UpdateSingleLED(int led) +{ + poseidon->SetLEDs(colors); +} \ No newline at end of file diff --git a/RGBController/RGBController_PoseidonZRGB.h b/RGBController/RGBController_PoseidonZRGB.h new file mode 100644 index 000000000..231c17401 --- /dev/null +++ b/RGBController/RGBController_PoseidonZRGB.h @@ -0,0 +1,28 @@ +/*-----------------------------------------*\ +| RGBController_PoseidonZRGB.h | +| | +| Generic RGB Interface for Thermaltake | +| Poseidon Z RGB Keyboard | +| | +| Adam Honse (CalcProgrammer1) 12/25/2019 | +\*-----------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "PoseidonZRGBController.h" + +class RGBController_PoseidonZRGB : public RGBController +{ +public: + RGBController_PoseidonZRGB(PoseidonZRGBController* poseidon_ptr); + ~RGBController_PoseidonZRGB(); + int GetMode(); + void SetMode(int mode); + void SetCustomMode(); + void UpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + +private: + PoseidonZRGBController* poseidon; +}; \ No newline at end of file diff --git a/dependencies/hidapi-win/x64/hidapi.dll b/dependencies/hidapi-win/x64/hidapi.dll new file mode 100644 index 0000000000000000000000000000000000000000..cea5b091aada2e7d5b5161e8ce380dd26cc636d5 GIT binary patch literal 18432 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 Bcm@Cf literal 0 HcmV?d00001 diff --git a/dependencies/hidapi-win/x64/hidapi.lib b/dependencies/hidapi-win/x64/hidapi.lib new file mode 100644 index 0000000000000000000000000000000000000000..eeebe3861f1c2863eb9c77398469af602bedee0f GIT binary patch literal 5186 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 literal 0 HcmV?d00001 diff --git a/dependencies/hidapi-win/x86/hidapi.lib b/dependencies/hidapi-win/x86/hidapi.lib new file mode 100644 index 0000000000000000000000000000000000000000..10e808950184c4081c87aa12e1c53e3d6a7de0f6 GIT binary patch literal 5270 zcmcInPj6F45Fgu=7$^Rl&_hL4qecP_O+&C#f~qQ{RBD6?Q84Eh$KJ$G*zZ}-&uVU! zIQPJbPtXIO0QHz7haP(95g|@|0?u`3-tKz$J+GZ-OrA8}-I<;J?at23j<5gN@S5$P zGT)cO-*>meV>wzEovphS(L2llzzu-(J%G$1z~W1Q>}yW>HULrKji5TVNcp#%mOcOw zK5}n*8{z) zWGBqGY^TLeSCx!N&Jv(SwV9epoHs`rQnL29v zX_smWA+^%^Ddn8#r3I$vhV!xx_Zzh(a&z5}jcz|Z;M8KXM!eG00#nOS+Wkbc_$V;O zZ-b_q?m_Y=C3~aorBc-Dl5e&*NmYb$8xv2nE)ByeO(iUn8Ewf0krYWxZof${Aa`X-8l0>?;X{CJ?EE1IqTPnV&KlzS zjnxe)!ejw|BfS@l6t>&2ekSH^3N~g0fd7!*O9r;vP(DjyTf|&JUq&731}qmAkVVVU zm&4TZ!Y)0so1WWukNxt^gInd=?%qQ#4*wDsDbfOfd5U_N^e|IVPl4bLnr^p;TYX_C z62qZ{BMtg!Z%L3R-o`XZoVMfyXCs`HBE`Vk+k1#nl4s7b;;{(eeE z{9InLQP~>Rm9<1N@RGlRozecxUeXFg>PPdEJCaLY@~0e#mb~O5Za>bQevNyWSbS=3 z7%#Rqe%REk#$)SWMBq1Uw%U}~s!BtVA5v`TpB7sc$)|b$$bo1-r*-346ifbzRlAC~ zc=oJp2y>RHexbOmVRR0MUj}DO^E!;bDQamgu4AIeON*dKxX#!>K*glTt}2k5@qZGp9`^SM*J2LsrC%+ z$xs|z6y{|eGg5fWgSjam=!iew#B(m_n5Lpe16JL5-dUYu-?WY!sh1Rv{&2^`+??R6 zxA3f2bWCF{HV<-T0y0HOMj{7w-bJA-N|d06oC{@223yim_CCYh?bXVrjlI)Ro!@YtWJ0d%7|G|nBji|3Pj7? R@$ja-q(zCx|7d6^{{zbkWI_M{ literal 0 HcmV?d00001 diff --git a/dependencies/hidapi/hidapi.h b/dependencies/hidapi/hidapi.h new file mode 100644 index 000000000..1819f8de0 --- /dev/null +++ b/dependencies/hidapi/hidapi.h @@ -0,0 +1,395 @@ +/******************************************************* + HIDAPI - Multi-Platform library for + communication with HID devices. + + Alan Ott + Signal 11 Software + + 8/22/2009 + + Copyright 2009, All Rights Reserved. + + At the discretion of the user of this library, + this software may be licensed under the terms of the + GNU General Public License v3, a BSD-Style license, or the + original HIDAPI license as outlined in the LICENSE.txt, + LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt + files located at the root of the source distribution. + These files may also be found in the public source + code repository located at: + http://github.com/signal11/hidapi . +********************************************************/ + +/** @file + * @defgroup API hidapi API + */ + +#ifndef HIDAPI_H__ +#define HIDAPI_H__ + +#include + +#ifdef _WIN32 + #define HID_API_EXPORT __declspec(dllexport) + #define HID_API_CALL +#else + #define HID_API_EXPORT /**< API export macro */ + #define HID_API_CALL /**< API call macro */ +#endif + +#define HID_API_EXPORT_CALL HID_API_EXPORT HID_API_CALL /**< API export and call macro*/ + +#ifdef __cplusplus +extern "C" { +#endif + struct hid_device_; + typedef struct hid_device_ hid_device; /**< opaque hidapi structure */ + + /** hidapi info structure */ + struct hid_device_info { + /** Platform-specific device path */ + char *path; + /** Device Vendor ID */ + unsigned short vendor_id; + /** Device Product ID */ + unsigned short product_id; + /** Serial Number */ + wchar_t *serial_number; + /** Device Release Number in binary-coded decimal, + also known as Device Version Number */ + unsigned short release_number; + /** Manufacturer String */ + wchar_t *manufacturer_string; + /** Product string */ + wchar_t *product_string; + /** Usage Page for this Device/Interface + (Windows/Mac only). */ + unsigned short usage_page; + /** Usage for this Device/Interface + (Windows/Mac only).*/ + unsigned short usage; + /** The USB interface which this logical device + represents. + + * Valid on both Linux implementations in all cases. + * Valid on the Windows implementation only if the device + contains more than one interface. + * Valid on the Mac implementation if and only if the device + is a USB HID device. */ + int interface_number; + + /** Pointer to the next device */ + struct hid_device_info *next; + }; + + + /** @brief Initialize the HIDAPI library. + + This function initializes the HIDAPI library. Calling it is not + strictly necessary, as it will be called automatically by + hid_enumerate() and any of the hid_open_*() functions if it is + needed. This function should be called at the beginning of + execution however, if there is a chance of HIDAPI handles + being opened by different threads simultaneously. + + @ingroup API + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_init(void); + + /** @brief Finalize the HIDAPI library. + + This function frees all of the static data associated with + HIDAPI. It should be called at the end of execution to avoid + memory leaks. + + @ingroup API + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_exit(void); + + /** @brief Enumerate the HID Devices. + + This function returns a linked list of all the HID devices + attached to the system which match vendor_id and product_id. + If @p vendor_id is set to 0 then any vendor matches. + If @p product_id is set to 0 then any product matches. + If @p vendor_id and @p product_id are both set to 0, then + all HID devices will be returned. + + @ingroup API + @param vendor_id The Vendor ID (VID) of the types of device + to open. + @param product_id The Product ID (PID) of the types of + device to open. + + @returns + This function returns a pointer to a linked list of type + struct #hid_device_info, containing information about the HID devices + attached to the system, or NULL in the case of failure. Free + this linked list by calling hid_free_enumeration(). + */ + struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id); + + /** @brief Free an enumeration Linked List + + This function frees a linked list created by hid_enumerate(). + + @ingroup API + @param devs Pointer to a list of struct_device returned from + hid_enumerate(). + */ + void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs); + + /** @brief Open a HID device using a Vendor ID (VID), Product ID + (PID) and optionally a serial number. + + If @p serial_number is NULL, the first device with the + specified VID and PID is opened. + + @ingroup API + @param vendor_id The Vendor ID (VID) of the device to open. + @param product_id The Product ID (PID) of the device to open. + @param serial_number The Serial Number of the device to open + (Optionally NULL). + + @returns + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ + HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number); + + /** @brief Open a HID device by its path name. + + The path name be determined by calling hid_enumerate(), or a + platform-specific path name can be used (eg: /dev/hidraw0 on + Linux). + + @ingroup API + @param path The path name of the device to open + + @returns + This function returns a pointer to a #hid_device object on + success or NULL on failure. + */ + HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path); + + /** @brief Write an Output report to a HID device. + + The first byte of @p data[] must contain the Report ID. For + devices which only support a single report, this must be set + to 0x0. The remaining bytes contain the report data. Since + the Report ID is mandatory, calls to hid_write() will always + contain one more byte than the report contains. For example, + if a hid report is 16 bytes long, 17 bytes must be passed to + hid_write(), the Report ID (or 0x0, for devices with a + single report), followed by the report data (16 bytes). In + this example, the length passed in would be 17. + + hid_write() will send the data on the first OUT endpoint, if + one exists. If it does not, it will send the data through + the Control Endpoint (Endpoint 0). + + @ingroup API + @param dev A device handle returned from hid_open(). + @param data The data to send, including the report number as + the first byte. + @param length The length in bytes of the data to send. + + @returns + This function returns the actual number of bytes written and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length); + + /** @brief Read an Input report from a HID device with timeout. + + Input reports are returned + to the host through the INTERRUPT IN endpoint. The first byte will + contain the Report number if the device uses numbered reports. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for + the report number. + @param milliseconds timeout in milliseconds or -1 for blocking wait. + + @returns + This function returns the actual number of bytes read and + -1 on error. If no packet was available to be read within + the timeout period, this function returns 0. + */ + int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds); + + /** @brief Read an Input report from a HID device. + + Input reports are returned + to the host through the INTERRUPT IN endpoint. The first byte will + contain the Report number if the device uses numbered reports. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param data A buffer to put the read data into. + @param length The number of bytes to read. For devices with + multiple reports, make sure to read an extra byte for + the report number. + + @returns + This function returns the actual number of bytes read and + -1 on error. If no packet was available to be read and + the handle is in non-blocking mode, this function returns 0. + */ + int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length); + + /** @brief Set the device handle to be non-blocking. + + In non-blocking mode calls to hid_read() will return + immediately with a value of 0 if there is no data to be + read. In blocking mode, hid_read() will wait (block) until + there is data to read before returning. + + Nonblocking can be turned on and off at any time. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param nonblock enable or not the nonblocking reads + - 1 to enable nonblocking + - 0 to disable nonblocking. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock); + + /** @brief Send a Feature report to the device. + + Feature reports are sent over the Control endpoint as a + Set_Report transfer. The first byte of @p data[] must + contain the Report ID. For devices which only support a + single report, this must be set to 0x0. The remaining bytes + contain the report data. Since the Report ID is mandatory, + calls to hid_send_feature_report() will always contain one + more byte than the report contains. For example, if a hid + report is 16 bytes long, 17 bytes must be passed to + hid_send_feature_report(): the Report ID (or 0x0, for + devices which do not use numbered reports), followed by the + report data (16 bytes). In this example, the length passed + in would be 17. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param data The data to send, including the report number as + the first byte. + @param length The length in bytes of the data to send, including + the report number. + + @returns + This function returns the actual number of bytes written and + -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length); + + /** @brief Get a feature report from a HID device. + + Set the first byte of @p data[] to the Report ID of the + report to be read. Make sure to allow space for this + extra byte in @p data[]. Upon return, the first byte will + still contain the Report ID, and the report data will + start in data[1]. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param data A buffer to put the read data into, including + the Report ID. Set the first byte of @p data[] to the + Report ID of the report to be read, or set it to zero + if your device does not use numbered reports. + @param length The number of bytes to read, including an + extra byte for the report ID. The buffer can be longer + than the actual report. + + @returns + This function returns the number of bytes read plus + one for the report ID (which is still in the first + byte), or -1 on error. + */ + int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length); + + /** @brief Close a HID device. + + @ingroup API + @param dev A device handle returned from hid_open(). + */ + void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev); + + /** @brief Get The Manufacturer String from a HID device. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen); + + /** @brief Get The Product String from a HID device. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen); + + /** @brief Get The Serial Number String from a HID device. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen); + + /** @brief Get a string from a HID device, based on its string index. + + @ingroup API + @param dev A device handle returned from hid_open(). + @param string_index The index of the string to get. + @param string A wide string buffer to put the data into. + @param maxlen The length of the buffer in multiples of wchar_t. + + @returns + This function returns 0 on success and -1 on error. + */ + int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen); + + /** @brief Get a string describing the last error which occurred. + + @ingroup API + @param dev A device handle returned from hid_open(). + + @returns + This function returns a string containing the last error + which occurred or NULL if none has occurred. + */ + HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *dev); + +#ifdef __cplusplus +} +#endif + +#endif +