From 069e07c690a3c391cf4e2651eddbf15bd3374e5b Mon Sep 17 00:00:00 2001 From: morg Date: Sat, 12 Feb 2022 04:15:33 +0000 Subject: [PATCH] Adds ZET-GAMING-Edge-Air-Pro mouse support --- 60-openrgb.rules | 3 + .../RGBController_ZETEdgeAirPro.cpp | 140 ++++++++++++++++++ .../RGBController_ZETEdgeAirPro.h | 31 ++++ .../ZETEdgeAirProController.cpp | 129 ++++++++++++++++ .../ZETEdgeAirProController.h | 54 +++++++ .../ZETEdgeAirProControllerDetect.cpp | 36 +++++ OpenRGB.pro | 5 + 7 files changed, 398 insertions(+) create mode 100644 Controllers/ZETEdgeAirProController/RGBController_ZETEdgeAirPro.cpp create mode 100644 Controllers/ZETEdgeAirProController/RGBController_ZETEdgeAirPro.h create mode 100644 Controllers/ZETEdgeAirProController/ZETEdgeAirProController.cpp create mode 100644 Controllers/ZETEdgeAirProController/ZETEdgeAirProController.h create mode 100644 Controllers/ZETEdgeAirProController/ZETEdgeAirProControllerDetect.cpp diff --git a/60-openrgb.rules b/60-openrgb.rules index 4a7e0017..beaac290 100644 --- a/60-openrgb.rules +++ b/60-openrgb.rules @@ -870,3 +870,6 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1c57", ATTR{idProduct}=="7ed0", TAG+="uacces # ZET Devices # #---------------------------------------------------------------# SUBSYSTEMS=="usb", ATTR{idVendor}=="2ea8", ATTR{idProduct}=="2125", TAG+="uaccess" +SUBSYSTEMS=="usb", ATTR{idVendor}=="25a7", ATTR{idProduct}=="fa3f", TAG+="uaccess" +SUBSYSTEMS=="usb", ATTR{idVendor}=="25a7", ATTR{idProduct}=="fa40", TAG+="uaccess" + diff --git a/Controllers/ZETEdgeAirProController/RGBController_ZETEdgeAirPro.cpp b/Controllers/ZETEdgeAirProController/RGBController_ZETEdgeAirPro.cpp new file mode 100644 index 00000000..5249eacf --- /dev/null +++ b/Controllers/ZETEdgeAirProController/RGBController_ZETEdgeAirPro.cpp @@ -0,0 +1,140 @@ +/*-----------------------------------------*\ +| RGBController_ZETEdgeAirPro.cpp | +| | +| Generic RGB Interface for OpenRGB | +| ZET Edge Air Pro RGB USB Driver | +| | +| Guimard Morgan (morg) 1/29/2022 | +\*-----------------------------------------*/ +#include "RGBController_ZETEdgeAirPro.h" + +#include +#include + +RGBController_ZETEdgeAirPro::RGBController_ZETEdgeAirPro(ZETEdgeAirProController* controller_ptr) +{ + controller = controller_ptr; + name = "ZET Edge Air Pro"; + vendor = "ZET Gaming"; + type = DEVICE_TYPE_MOUSE; + description = name; + location = controller->GetDeviceLocation(); + serial = controller->GetSerialString(); + version = controller->GetFirmwareVersion(); + + mode Static; + Static.name = "Static"; + Static.value = STATIC_MODE_VALUE; + Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; + Static.color_mode = MODE_COLORS_PER_LED; + Static.brightness_min = ZET_EDGE_AIR_PRO_BRIGHTNESS_MIN; + Static.brightness_max = ZET_EDGE_AIR_PRO_BRIGHTNESS_MAX; + Static.brightness = ZET_EDGE_AIR_PRO_BRIGHTNESS_MAX; + modes.push_back(Static); + + mode OFF; + OFF.name = "Off"; + OFF.value = OFF_MODE_VALUE; + OFF.flags = MODE_FLAG_AUTOMATIC_SAVE; + OFF.color_mode = MODE_COLORS_NONE; + modes.push_back(OFF); + + mode Rainbow; + Rainbow.name = "Rainbow"; + Rainbow.value = RAINBOW_MODE_VALUE; + Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; + Rainbow.color_mode = MODE_COLORS_NONE; + Rainbow.brightness_min = ZET_EDGE_AIR_PRO_BRIGHTNESS_MIN; + Rainbow.brightness_max = ZET_EDGE_AIR_PRO_BRIGHTNESS_MAX; + Rainbow.brightness = ZET_EDGE_AIR_PRO_BRIGHTNESS_MAX; + Rainbow.speed_min = ZET_EDGE_AIR_PRO_SPEED_MIN; + Rainbow.speed_max = ZET_EDGE_AIR_PRO_SPEED_MAX; + Rainbow.speed = ZET_EDGE_AIR_PRO_SPEED_MIN; + modes.push_back(Rainbow); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = BREATHING_MODE_VALUE; + Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; + Breathing.color_mode = MODE_COLORS_PER_LED; + Breathing.brightness_min = ZET_EDGE_AIR_PRO_BRIGHTNESS_MIN; + Breathing.brightness_max = ZET_EDGE_AIR_PRO_BRIGHTNESS_MAX; + Breathing.brightness = ZET_EDGE_AIR_PRO_BRIGHTNESS_MAX; + Breathing.speed_min = ZET_EDGE_AIR_PRO_SPEED_MIN; + Breathing.speed_max = ZET_EDGE_AIR_PRO_SPEED_MAX; + Breathing.speed = ZET_EDGE_AIR_PRO_SPEED_MIN; + Breathing.colors.resize(1); + modes.push_back(Breathing); + + SetupZones(); +} + +RGBController_ZETEdgeAirPro::~RGBController_ZETEdgeAirPro() +{ + delete controller; +} + +void RGBController_ZETEdgeAirPro::SetupZones() +{ + zone new_zone; + + new_zone.name = "Mouse"; + new_zone.type = ZONE_TYPE_LINEAR; + new_zone.leds_min = 1; + new_zone.leds_max = 1; + new_zone.leds_count = 1; + new_zone.matrix_map = nullptr; + + zones.emplace_back(new_zone); + + leds.resize(1); + + led new_led; + new_led.name = "LED 1"; + leds[0] = new_led; + + SetupColors(); +} + +void RGBController_ZETEdgeAirPro::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_ZETEdgeAirPro::DeviceUpdateLEDs() +{ + DeviceUpdateMode(); +} + +void RGBController_ZETEdgeAirPro::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateMode(); +} + +void RGBController_ZETEdgeAirPro::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateMode(); +} + +void RGBController_ZETEdgeAirPro::SetCustomMode() +{ + active_mode = 0; +} + +void RGBController_ZETEdgeAirPro::DeviceUpdateMode() +{ + RGBColor color; + + if(modes[active_mode].flags & MODE_FLAG_HAS_PER_LED_COLOR) + { + color = colors[0]; + } + else + { + color = ToRGBColor(0,0,0); + } + + controller->SetMode(color, modes[active_mode].brightness, modes[active_mode].speed, modes[active_mode].value); +} diff --git a/Controllers/ZETEdgeAirProController/RGBController_ZETEdgeAirPro.h b/Controllers/ZETEdgeAirProController/RGBController_ZETEdgeAirPro.h new file mode 100644 index 00000000..c60f34fd --- /dev/null +++ b/Controllers/ZETEdgeAirProController/RGBController_ZETEdgeAirPro.h @@ -0,0 +1,31 @@ +/*-----------------------------------------*\ +| RGBController_ZETEdgeAirPro.h | +| | +| Generic RGB Interface for OpenRGB | +| ZET Edge Air Pro RGB USB Driver | +| | +| Guimard Morgan (morg) 1/29/2022 | +\*-----------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "ZETEdgeAirProController.h" + +class RGBController_ZETEdgeAirPro : public RGBController +{ +public: + RGBController_ZETEdgeAirPro(ZETEdgeAirProController* controller_ptr); + ~RGBController_ZETEdgeAirPro(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + void DeviceUpdateMode(); + void SetCustomMode(); + +private: + ZETEdgeAirProController* controller; +}; diff --git a/Controllers/ZETEdgeAirProController/ZETEdgeAirProController.cpp b/Controllers/ZETEdgeAirProController/ZETEdgeAirProController.cpp new file mode 100644 index 00000000..65f7e3b8 --- /dev/null +++ b/Controllers/ZETEdgeAirProController/ZETEdgeAirProController.cpp @@ -0,0 +1,129 @@ +/*-----------------------------------------*\ +| ZETEdgeAirProController.cpp | +| | +| Driver for ZET Edge Air Pro mouse | +| lighting controller | +| | +| Guimard Morgan (morg) 1/29/2022 | +\*-----------------------------------------*/ +#include "ZETEdgeAirProController.h" +#include + +ZETEdgeAirProController::ZETEdgeAirProController(hid_device* dev_handle, const hid_device_info& info) +{ + dev = dev_handle; + location = info.path; + version = ""; + + wchar_t serial_string[128]; + int ret = hid_get_serial_number_string(dev, serial_string, 128); + + if(ret != 0) + { + serial_number = ""; + } + else + { + std::wstring return_wstring = serial_string; + serial_number = std::string(return_wstring.begin(), return_wstring.end()); + } +} + +ZETEdgeAirProController::~ZETEdgeAirProController() +{ + hid_close(dev); +} + +std::string ZETEdgeAirProController::GetDeviceLocation() +{ + return("HID: " + location); +} + +std::string ZETEdgeAirProController::GetSerialString() +{ + return(serial_number); +} + +std::string ZETEdgeAirProController::GetFirmwareVersion() +{ + return(version); +} + +void ZETEdgeAirProController::SetMode(RGBColor color, unsigned char brightness, unsigned char speed, unsigned char mode_value) +{ + /*---------------------------------------------------------*\ + | Init the packet buffer | + \*---------------------------------------------------------*/ + unsigned char usb_buf[ZET_EDGE_AIR_PRO_PACKET_SIZE]; + + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*---------------------------------------------------------*\œ + | Constant data | + \*---------------------------------------------------------*/ + usb_buf[0x00] = ZET_EDGE_AIR_PRO_REPORT_ID; + usb_buf[0x01] = 0x07; + usb_buf[0x04] = 0xA0; + usb_buf[0x05] = 0x07; + + /*---------------------------------------------------------*\ + | Set the mode | + \*---------------------------------------------------------*/ + usb_buf[0x06] = mode_value; + + /*---------------------------------------------------------*\ + | Set the color | + \*---------------------------------------------------------*/ + usb_buf[0x07] = RGBGetRValue(color); + usb_buf[0x08] = RGBGetGValue(color); + usb_buf[0x09] = RGBGetBValue(color); + + /*---------------------------------------------------------*\ + | Set speed if needed | + \*---------------------------------------------------------*/ + if(mode_value == BREATHING_MODE_VALUE) + { + unsigned char speed_values[ZET_EDGE_AIR_PRO_SPEED_MAX] = + { + 0xFF, 0xE6, 0xD2, 0xBe, 0xAA, 0x96, 0x82, 0x6E, 0x46, 0x28 + }; + + usb_buf[0x0A] = speed_values[speed - 1]; + } + else if(mode_value == RAINBOW_MODE_VALUE) + { + unsigned char speed_values[ZET_EDGE_AIR_PRO_SPEED_MAX] = + { + 0x2D, 0x28, 0x23, 0x1E, 0x19, 0x13, 0x0F, 0x0A, 0x05, 0x03 + }; + + usb_buf[0x0A] = speed_values[speed - 1]; + } + /*---------------------------------------------------------*\ + | Set brightness if needed | + \*---------------------------------------------------------*/ + if(mode_value != OFF_MODE_VALUE) + { + unsigned char brightness_values[ZET_EDGE_AIR_PRO_BRIGHTNESS_MAX] = + { + 0x19, 0x32, 0x4B, 0x64, 0x7D, 0x96, 0xAF, 0xC8, 0xE1, 0xFF + }; + + usb_buf[0x0B] = brightness_values[brightness - 1]; + } + + /*---------------------------------------------------------*\ + | Custom CRC - thanks to Vaker for this <3 | + \*---------------------------------------------------------*/ + usb_buf[0x0C] = 0x55 - usb_buf[0x06] - usb_buf[0x07] - usb_buf[0x08] - usb_buf[0x09] - usb_buf[0x0A] - usb_buf[0x0B]; + + /*---------------------------------------------------------*\ + | Constant data | + \*---------------------------------------------------------*/ + usb_buf[0x10] = ZET_EDGE_AIR_PRO_PACKET_END; + + /*---------------------------------------------------------*\ + | Send the report | + \*---------------------------------------------------------*/ + hid_send_feature_report(dev, usb_buf, ZET_EDGE_AIR_PRO_PACKET_SIZE); +} diff --git a/Controllers/ZETEdgeAirProController/ZETEdgeAirProController.h b/Controllers/ZETEdgeAirProController/ZETEdgeAirProController.h new file mode 100644 index 00000000..f45e0ce7 --- /dev/null +++ b/Controllers/ZETEdgeAirProController/ZETEdgeAirProController.h @@ -0,0 +1,54 @@ +/*-----------------------------------------*\ +| ZETEdgeAirProController.h | +| | +| Driver for ZET Edge Air Pro mouse | +| lighting controller - header file | +| | +| Guimard Morgan (morg) 1/29/2022 | +\*-----------------------------------------*/ +#pragma once + +#include "RGBController.h" +#include +#include + +#define ZET_EDGE_AIR_PRO_PACKET_SIZE 17 +#define ZET_EDGE_AIR_PRO_REPORT_ID 0x08 +#define ZET_EDGE_AIR_PRO_PACKET_END 0x4a + +enum +{ + STATIC_MODE_VALUE = 0x02, + OFF_MODE_VALUE = 0x04, + RAINBOW_MODE_VALUE = 0x00, + BREATHING_MODE_VALUE = 0x01 +}; + +enum +{ + ZET_EDGE_AIR_PRO_BRIGHTNESS_MIN = 1, + ZET_EDGE_AIR_PRO_BRIGHTNESS_MAX = 10, + ZET_EDGE_AIR_PRO_SPEED_MIN = 1, + ZET_EDGE_AIR_PRO_SPEED_MAX = 10 +}; + +class ZETEdgeAirProController +{ +public: + ZETEdgeAirProController(hid_device* dev_handle, const hid_device_info& info); + ~ZETEdgeAirProController(); + + std::string GetSerialString(); + std::string GetDeviceLocation(); + std::string GetFirmwareVersion(); + + void SetMode(RGBColor color, unsigned char brightness, unsigned char speed, unsigned char mode_value); + +protected: + hid_device* dev; + +private: + std::string location; + std::string serial_number; + std::string version; +}; diff --git a/Controllers/ZETEdgeAirProController/ZETEdgeAirProControllerDetect.cpp b/Controllers/ZETEdgeAirProController/ZETEdgeAirProControllerDetect.cpp new file mode 100644 index 00000000..c0f217dd --- /dev/null +++ b/Controllers/ZETEdgeAirProController/ZETEdgeAirProControllerDetect.cpp @@ -0,0 +1,36 @@ +#include "Detector.h" +#include "ZETEdgeAirProController.h" +#include "RGBController.h" +#include "RGBController_ZETEdgeAirPro.h" + +/*---------------------------------------------------------*\ +| ZET GAMING vendor ID | +\*---------------------------------------------------------*/ +#define ZET_GAMING_VID 0x25A7 + +/*---------------------------------------------------------*\ +| Product ID | +\*---------------------------------------------------------*/ +#define ZET_GAMING_EDGE_AIR_PRO_WIRELESS_PID 0xFA3F +#define ZET_GAMING_EDGE_AIR_PRO_PID 0xFA40 +#define ZET_GAMING_EDGE_AIR_ELIT_WIRELESS_PID 0xFA48 +#define ZET_GAMING_EDGE_AIR_ELIT_PID 0xFA49 + +void DetectZETGAMINGEdgeAirProControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + ZETEdgeAirProController* controller = new ZETEdgeAirProController(dev, *info); + RGBController_ZETEdgeAirPro* rgb_controller = new RGBController_ZETEdgeAirPro(controller); + + rgb_controller->name = name; + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR_IPU("ZET GAMING Edge Air Pro (Wireless)", DetectZETGAMINGEdgeAirProControllers, ZET_GAMING_VID, ZET_GAMING_EDGE_AIR_PRO_WIRELESS_PID, 1, 0xFF02, 2); +REGISTER_HID_DETECTOR_IPU("ZET GAMING Edge Air Pro", DetectZETGAMINGEdgeAirProControllers, ZET_GAMING_VID, ZET_GAMING_EDGE_AIR_PRO_PID, 1, 0xFF02, 2); +REGISTER_HID_DETECTOR_IPU("ZET GAMING Edge Air Elit (Wireless)", DetectZETGAMINGEdgeAirProControllers, ZET_GAMING_VID, ZET_GAMING_EDGE_AIR_ELIT_WIRELESS_PID, 1, 0xFF02, 2); +REGISTER_HID_DETECTOR_IPU("ZET GAMING Edge Air Elit", DetectZETGAMINGEdgeAirProControllers, ZET_GAMING_VID, ZET_GAMING_EDGE_AIR_ELIT_PID, 1, 0xFF02, 2); diff --git a/OpenRGB.pro b/OpenRGB.pro index 645b1654..9a0e293a 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -496,6 +496,8 @@ HEADERS += Controllers/YeelightController/RGBController_Yeelight.h \ Controllers/ZalmanZSyncController/ZalmanZSyncController.h \ Controllers/ZalmanZSyncController/RGBController_ZalmanZSync.h \ + Controllers/ZETEdgeAirProController/ZETEdgeAirProController.h \ + Controllers/ZETEdgeAirProController/RGBController_ZETEdgeAirPro.h \ Controllers/ZETKeyboardController/ZETBladeOpticalController.h \ Controllers/ZETKeyboardController/RGBController_ZETBladeOptical.h \ RGBController/RGBController.h \ @@ -943,6 +945,9 @@ SOURCES += Controllers/ZalmanZSyncController/ZalmanZSyncController.cpp \ Controllers/ZalmanZSyncController/ZalmanZSyncControllerDetect.cpp \ Controllers/ZalmanZSyncController/RGBController_ZalmanZSync.cpp \ + Controllers/ZETEdgeAirProController/ZETEdgeAirProController.cpp \ + Controllers/ZETEdgeAirProController/ZETEdgeAirProControllerDetect.cpp \ + Controllers/ZETEdgeAirProController/RGBController_ZETEdgeAirPro.cpp \ Controllers/ZETKeyboardController/ZETBladeOpticalController.cpp \ Controllers/ZETKeyboardController/ZETKeyboardControllerDetect.cpp \ Controllers/ZETKeyboardController/RGBController_ZETBladeOptical.cpp \