From 6db00be29ac83b35b787a4311fd50ed620db6ae4 Mon Sep 17 00:00:00 2001 From: Shenghao Yang Date: Sun, 13 Mar 2022 18:56:14 +0000 Subject: [PATCH] Add support for Acer monitors with rear RGB strips Amended for code style by Adam Honse --- .../AcerMonitorController.cpp | 75 ++++++++++++ .../AcerMonitorController.h | 48 ++++++++ .../AcerMonitorControllerDetect.cpp | 50 ++++++++ .../RGBController_AcerMonitor.cpp | 111 ++++++++++++++++++ .../RGBController_AcerMonitor.h | 35 ++++++ OpenRGB.pro | 6 + 6 files changed, 325 insertions(+) create mode 100644 Controllers/AcerMonitorController/AcerMonitorController.cpp create mode 100644 Controllers/AcerMonitorController/AcerMonitorController.h create mode 100644 Controllers/AcerMonitorController/AcerMonitorControllerDetect.cpp create mode 100644 Controllers/AcerMonitorController/RGBController_AcerMonitor.cpp create mode 100644 Controllers/AcerMonitorController/RGBController_AcerMonitor.h diff --git a/Controllers/AcerMonitorController/AcerMonitorController.cpp b/Controllers/AcerMonitorController/AcerMonitorController.cpp new file mode 100644 index 000000000..4f79ee758 --- /dev/null +++ b/Controllers/AcerMonitorController/AcerMonitorController.cpp @@ -0,0 +1,75 @@ +/*---------------------------------------------------------*\ +| AcerMonitorController.cpp | +| | +| Driver for 2020/2021 Acer monitors with rear RGB strips. | +| | +| Shenghao Yang (me@shenghaoyang.info), 30/12/2021 | +| Amended for code style by Adam Honse, 3/13/2022 | +\*---------------------------------------------------------*/ + +#include "AcerMonitorController.h" +#include + +AcerMonitorController::AcerMonitorController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; +} + +AcerMonitorController::~AcerMonitorController() +{ + hid_close(dev); +} + +std::string AcerMonitorController::GetDeviceLocation() +{ + return("HID: " + location); +} + +std::string AcerMonitorController::GetSerialString() +{ + wchar_t serial_string[128]; + int ret = hid_get_serial_number_string(dev, serial_string, 128); + + if(ret != 0) + { + return(""); + } + + std::wstring return_wstring = serial_string; + std::string return_string(return_wstring.begin(), return_wstring.end()); + + return(return_string); +} + +void AcerMonitorController::SetColors(RGBColor *colors, std::size_t num_leds) +{ + char usb_buf[374]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Fill in Set Colors packet | + \*-----------------------------------------------------*/ + usb_buf[ACER_MONITOR_OFFSET_REPORT_TYPE] = ACER_MONITOR_REPORT_TYPE; + usb_buf[ACER_MONITOR_OFFSET_MAGIC_0] = ACER_MONITOR_MAGIC_0; + usb_buf[ACER_MONITOR_OFFSET_MAGIC_1] = ACER_MONITOR_MAGIC_1; + + /*-----------------------------------------------------*\ + | Fill in color data | + \*-----------------------------------------------------*/ + for(unsigned int color_idx = 0; color_idx < num_leds; color_idx++) + { + usb_buf[ACER_MONITOR_OFFSET_RGB_DATA + 0 + (color_idx * 3)] = RGBGetRValue(colors[color_idx]); + usb_buf[ACER_MONITOR_OFFSET_RGB_DATA + 1 + (color_idx * 3)] = RGBGetGValue(colors[color_idx]); + usb_buf[ACER_MONITOR_OFFSET_RGB_DATA + 2 + (color_idx * 3)] = RGBGetBValue(colors[color_idx]); + } + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_write(dev, (unsigned char *)usb_buf, 374); +} diff --git a/Controllers/AcerMonitorController/AcerMonitorController.h b/Controllers/AcerMonitorController/AcerMonitorController.h new file mode 100644 index 000000000..db3e043d9 --- /dev/null +++ b/Controllers/AcerMonitorController/AcerMonitorController.h @@ -0,0 +1,48 @@ +/*---------------------------------------------------------*\ +| AcerMonitorController.h | +| | +| Driver for 2020/2021 Acer monitors with rear RGB strips. | +| | +| Shenghao Yang (me@shenghaoyang.info), 30/12/2021 | +| Amended for code style by Adam Honse, 3/13/2022 | +\*---------------------------------------------------------*/ + +#pragma once + +#include +#include + +enum +{ + ACER_MONITOR_OFFSET_REPORT_TYPE = 0x00, /* Offset of report type field in packet */ + ACER_MONITOR_OFFSET_MAGIC_0 = 0x01, /* Offset of magic 0 field in packet */ + ACER_MONITOR_OFFSET_MAGIC_1 = 0x02, /* Offset of magic 1 field in packet */ + ACER_MONITOR_OFFSET_PAD_0 = 0x03, /* Offset of pad 0 field in packet */ + ACER_MONITOR_OFFSET_NUM_LEDS = 0x04, /* Offset of number of LEDs field in packet */ + ACER_MONITOR_OFFSET_STRIP_INDEX = 0x05, /* Offset of strip index field in packet */ + ACER_MONITOR_OFFSET_PAD_1 = 0x06, /* Offset of pad 1 field in packet */ + ACER_MONITOR_OFFSET_RGB_DATA = 0x0E, /* Offset of RGB data field in packet */ +}; + +enum +{ + ACER_MONITOR_REPORT_TYPE = 0x2A, /* Value of report type field in packet */ + ACER_MONITOR_MAGIC_0 = 0x0C, /* Value of magic 0 field in packet */ + ACER_MONITOR_MAGIC_1 = 0x02, /* Value of magic 1 field in packet */ +}; + +class AcerMonitorController +{ +public: + AcerMonitorController(hid_device* dev_handle, const char* path); + ~AcerMonitorController(); + + std::string GetDeviceLocation(); + std::string GetSerialString(); + + void SetColors(RGBColor *colors, std::size_t num_leds); + +private: + hid_device* dev; + std::string location; +}; diff --git a/Controllers/AcerMonitorController/AcerMonitorControllerDetect.cpp b/Controllers/AcerMonitorController/AcerMonitorControllerDetect.cpp new file mode 100644 index 000000000..440299598 --- /dev/null +++ b/Controllers/AcerMonitorController/AcerMonitorControllerDetect.cpp @@ -0,0 +1,50 @@ +/*---------------------------------------------------------*\ +| AcerMonitorControllerDetect.cpp | +| | +| Controller detection for 2020/2021 Acer monitors | +| with rear RGB strips. | +| | +| Shenghao Yang (me@shenghaoyang.info), 30/12/2021 | +| Amended for code style by Adam Honse, 3/13/2022 | +\*---------------------------------------------------------*/ + +#include "Detector.h" +#include "AcerMonitorController.h" +#include "RGBController_AcerMonitor.h" + +/*-----------------------------------------------------*\ +| Acer vendor ID | +\*-----------------------------------------------------*/ +#define ACER_VID 0x042E + +/*-----------------------------------------------------*\ +| Acer monitor product IDs | +\*-----------------------------------------------------*/ +#define ACER_XB323QK_NV_PID 0xAC0B +#define ACER_XB273U_NV_PID 0xAC0C +#define ACER_X25_PID 0xAC0D + +/*---------------------------------------------------------*\ +| DetectAcerMonitorControllers | +| | +| Detects Acer monitor controllers. | +| | +| info: HID device information. | +\*---------------------------------------------------------*/ +void DetectAcerMonitorControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + AcerMonitorController* controller = new AcerMonitorController(dev, info->path); + RGBController_AcerMonitor* rgb_controller = new RGBController_AcerMonitor(controller); + rgb_controller->name = name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR("Acer XB323QK NV", DetectAcerMonitorControllers, ACER_VID, ACER_XB323QK_NV_PID); +REGISTER_HID_DETECTOR("Acer XB273U NV", DetectAcerMonitorControllers, ACER_VID, ACER_XB273U_NV_PID ); +REGISTER_HID_DETECTOR("Acer X25", DetectAcerMonitorControllers, ACER_VID, ACER_X25_PID ); diff --git a/Controllers/AcerMonitorController/RGBController_AcerMonitor.cpp b/Controllers/AcerMonitorController/RGBController_AcerMonitor.cpp new file mode 100644 index 000000000..b161a6686 --- /dev/null +++ b/Controllers/AcerMonitorController/RGBController_AcerMonitor.cpp @@ -0,0 +1,111 @@ +/*---------------------------------------------------------*\ +| RGBController_AcerMonitor.cpp | +| | +| RGBController interface implementation for 2020/2021 | +| Acer monitors with rear RGB strips. | +| | +| Shenghao Yang (me@shenghaoyang.info), 30/12/2021 | +| Amended for code style by Adam Honse, 3/13/2022 | +\*---------------------------------------------------------*/ + +#include "RGBController_AcerMonitor.h" + +RGBController_AcerMonitor::RGBController_AcerMonitor(AcerMonitorController* controller_ptr) +{ + controller = controller_ptr; + vendor = "Acer"; + type = DEVICE_TYPE_LEDSTRIP; + description = "Acer Monitor Device"; + location = controller->GetDeviceLocation(); + serial = controller->GetSerialString(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = 0; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + SetupZones(); +} + +RGBController_AcerMonitor::~RGBController_AcerMonitor() +{ + delete controller; +} + +void RGBController_AcerMonitor::SetupZones() +{ + zones.clear(); + leds.clear(); + + // for(const auto *const *pz{ctrl->monitor->zones}; *pz; ++pz) + // { + // const Zone *z{*pz}; + // zone led_zone; + + // led_zone.leds_count = z->leds; + // led_zone.leds_max = led_zone.leds_count; + // led_zone.leds_min = led_zone.leds_count; + // led_zone.name = z->name; + // led_zone.type = z->type; + // led_zone.matrix_map = z->mmap; + + // for (std::size_t i{}; i < z->leds; ++i) + // { + // led new_led{}; + + // new_led.name = led_zone.name + " LED "; + // if (led_zone.leds_count > 1) + // new_led.name.append(std::to_string(i + 1)); + + // leds.emplace_back(new_led); + // } + + // zones.emplace_back(led_zone); + // } + + SetupColors(); +} + +void RGBController_AcerMonitor::ResizeZone(int, int) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_AcerMonitor::DeviceUpdateLEDs() +{ + // for (std::size_t i{}; i < zones.size(); ++i) + // UpdateZoneLEDs(i); +} + +void RGBController_AcerMonitor::UpdateZoneLEDs(int zone) +{ + //controller->SetLEDs(zone, zones[zone].colors); +} + +void RGBController_AcerMonitor::UpdateSingleLED(int led) +{ + // /*-----------------------------------------------------*\ + // | Find the zone that the LED exists in. | + // \*-----------------------------------------------------*/ + // std::size_t total{}; + // int zone{}; + // while (static_cast(led) >= total) + // total += zones[zone++].leds_count; + + // --zone; + // ctrl->SetLEDs(zone, zones[zone].colors); +} + +void RGBController_AcerMonitor::SetCustomMode() +{ + active_mode = 0; +} + +void RGBController_AcerMonitor::DeviceUpdateMode() +{ + +} diff --git a/Controllers/AcerMonitorController/RGBController_AcerMonitor.h b/Controllers/AcerMonitorController/RGBController_AcerMonitor.h new file mode 100644 index 000000000..8d5327217 --- /dev/null +++ b/Controllers/AcerMonitorController/RGBController_AcerMonitor.h @@ -0,0 +1,35 @@ +/*---------------------------------------------------------*\ +| RGBController_AcerMonitor.h | +| | +| RGBController interface implementation for 2020/2021 | +| Acer monitors with rear RGB strips. | +| | +| Shenghao Yang (me@shenghaoyang.info), 30/12/2021 | +| Amended for code style by Adam Honse, 3/13/2022 | +\*---------------------------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "AcerMonitorController.h" + +class RGBController_AcerMonitor : public RGBController +{ +public: + RGBController_AcerMonitor(AcerMonitorController* controller_ptr); + ~RGBController_AcerMonitor(); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void DeviceUpdateMode(); + +private: + AcerMonitorController* controller; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 0337762c6..97f88c302 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -110,6 +110,7 @@ INCLUDEPATH += qt/OpenRGBZoneResizeDialog/ \ qt/OpenRGBZonesBulkResizer/ \ Controllers/A4TechController/ \ + Controllers/AcerMonitorController/ \ Controllers/AlienwareController/ \ Controllers/AlienwareKeyboardController/ \ Controllers/AMDWraithPrismController/ \ @@ -310,6 +311,8 @@ HEADERS += AutoStart/AutoStart.h \ Controllers/A4TechController/BloodyMouseController.h \ Controllers/A4TechController/RGBController_BloodyMouse.h \ + Controllers/AcerMonitorController/AcerMonitorController.h \ + Controllers/AcerMonitorController/RGBController_AcerMonitor.h \ Controllers/AlienwareController/AlienwareController.h \ Controllers/AlienwareController/RGBController_Alienware.h \ Controllers/AlienwareKeyboardController/AlienwareAW510KController.h \ @@ -893,6 +896,9 @@ SOURCES += Controllers/A4TechController/A4Tech_Detector.cpp \ Controllers/A4TechController/BloodyMouseController.cpp \ Controllers/A4TechController/RGBController_BloodyMouse.cpp \ + Controllers/AcerMonitorController/AcerMonitorController.cpp \ + Controllers/AcerMonitorController/AcerMonitorControllerDetect.cpp \ + Controllers/AcerMonitorController/RGBController_AcerMonitor.cpp \ Controllers/AlienwareController/AlienwareController.cpp \ Controllers/AlienwareController/AlienwareControllerDetect.cpp \ Controllers/AlienwareController/RGBController_Alienware.cpp \