diff --git a/Controllers/AlienwareMonitorController/AlienwareAW3423DWFController.cpp b/Controllers/AlienwareMonitorController/AlienwareAW3423DWFController.cpp index 6955eb30d..e59e12fd7 100644 --- a/Controllers/AlienwareMonitorController/AlienwareAW3423DWFController.cpp +++ b/Controllers/AlienwareMonitorController/AlienwareAW3423DWFController.cpp @@ -9,10 +9,13 @@ | SPDX-License-Identifier: GPL-2.0-only | \*---------------------------------------------------------*/ +#include +#include +#include +#include + #include "AlienwareAW3423DWFController.h" #include "StringUtils.h" -#include -#include AlienwareAW3423DWFController::AlienwareAW3423DWFController(hid_device *dev_handle, const char *path) : dev(dev_handle), location(path){} @@ -37,7 +40,7 @@ std::vector AlienwareAW3423DWFController::GetReportResponse() void AlienwareAW3423DWFController::PerformLogin() { - unsigned char init_packet[64] = + unsigned char init_packet[64] = { 0x40, 0xE1, 0x01 }; @@ -83,6 +86,8 @@ void AlienwareAW3423DWFController::SendColor(unsigned char led_id, unsigned char color_packet[73] = led_id_2; SendControlPacket(color_packet, 192); + + std::this_thread::sleep_for(std::chrono::milliseconds(200)); } std::vector AlienwareAW3423DWFController::GenerateKey( @@ -119,10 +124,10 @@ std::vector AlienwareAW3423DWFController::GenerateKey( size_t end = std::min(8, response.size()); out_buffer = std::vector(response.begin(), response.begin() + end); - if(response.size() > 14) + if(response.size() > 14) { unsigned char idx = response[14] & 0x07; - if((idx + 8) < response.size()) + if((idx + 8) < response.size()) { out_buffer[idx] ^= response[idx + 8]; } @@ -134,17 +139,17 @@ std::vector AlienwareAW3423DWFController::GenerateKey( size_t end = std::min(start + 8, response.size()); out_buffer = std::vector(response.begin() + start, response.begin() + end); - if(response.size() > 6) + if(response.size() > 6) { unsigned char idx = response[6] & 0x07; - if(idx < response.size()) + if(idx < response.size()) { out_buffer[idx] ^= response[idx]; } } } - for(size_t i = 0; i < 8 && i < out_buffer.size(); i++) + for(size_t i = 0; i < 8 && i < out_buffer.size(); i++) { syn_key[i] ^= out_buffer[i]; } diff --git a/Controllers/AlienwareMonitorController/AlienwareMonitorController.cpp b/Controllers/AlienwareMonitorController/AlienwareMonitorController.cpp new file mode 100644 index 000000000..9458a5bc6 --- /dev/null +++ b/Controllers/AlienwareMonitorController/AlienwareMonitorController.cpp @@ -0,0 +1,136 @@ +/*---------------------------------------------------------*\ +| AlienwareMonitorController.cpp | +| | +| Detector for Alienware monitors | +| | +| Adam Honse (CalcProgrammer1) 08 May 2025 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include +#include +#include + +#include "AlienwareMonitorController.h" + +AlienwareMonitorController::AlienwareMonitorController(hid_device *dev_handle, const char *path) +{ + dev = dev_handle; + location = path; + + Initialize(); +} + +AlienwareMonitorController::~AlienwareMonitorController() +{ + hid_close(dev); +} + +std::string AlienwareMonitorController::GetLocation() +{ + return("HID: " + location); +} + +std::string AlienwareMonitorController::GetSerialString() +{ + return(""); +} + +void fillInChecksum(unsigned char *packet) +{ + unsigned char checksum = 110; + + for(unsigned int index = 5; index <= 13; index++) + { + checksum ^= packet[index]; + } + + packet[14] = checksum; +} + +void AlienwareMonitorController::SendColor(unsigned char led_id, unsigned char r, unsigned char g, unsigned char b) +{ + unsigned char packet[65]; + + memset(packet, 0xFF, sizeof(packet)); + + packet[1] = 0x92; + packet[2] = 0x37; + packet[3] = 0x0a; + packet[4] = 0x00; + packet[5] = 0x51; + packet[6] = 0x87; + packet[7] = 0xd0; + packet[8] = 0x04; + + packet[9] = led_id; + packet[10] = r; + packet[11] = g; + packet[12] = b; + packet[13] = 0x64; + + fillInChecksum(packet); + + hid_write(dev, packet, sizeof(packet)); + + /*-----------------------------------------------------*\ + | Delay 50 milliseconds | + \*-----------------------------------------------------*/ + std::this_thread::sleep_for(std::chrono::milliseconds(50)); +} + +void AlienwareMonitorController::Initialize() +{ + unsigned char packet[65]; + + memset(packet, 0xFF, sizeof(packet)); + + packet[1] = 0x95; + packet[2] = 0x00; + packet[3] = 0x00; + packet[4] = 0x00; + + hid_write(dev, packet, sizeof(packet)); + + /*-----------------------------------------------------*\ + | Delay 50 milliseconds | + \*-----------------------------------------------------*/ + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + + memset(packet, 0xFF, sizeof(packet)); + + packet[1] = 0x92; + packet[2] = 0x37; + packet[3] = 0x08; + packet[4] = 0x00; + packet[5] = 0x51; + packet[6] = 0x85; + packet[7] = 0x01; + packet[8] = 0xFE; + packet[9] = 0x03; + packet[10] = 0x00; + packet[11] = 0x06; + packet[12] = 0x40; + + hid_write(dev, packet, sizeof(packet)); + + /*-----------------------------------------------------*\ + | Delay 50 milliseconds | + \*-----------------------------------------------------*/ + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + + memset(packet, 0x00, sizeof(packet)); + + packet[1] = 0x93; + packet[2] = 0x37; + packet[3] = 0x12; + + hid_write(dev, packet, sizeof(packet)); + + /*-----------------------------------------------------*\ + | Delay 50 milliseconds | + \*-----------------------------------------------------*/ + std::this_thread::sleep_for(std::chrono::milliseconds(50)); +} diff --git a/Controllers/AlienwareMonitorController/AlienwareMonitorController.h b/Controllers/AlienwareMonitorController/AlienwareMonitorController.h new file mode 100644 index 000000000..4d1924e5f --- /dev/null +++ b/Controllers/AlienwareMonitorController/AlienwareMonitorController.h @@ -0,0 +1,33 @@ +/*---------------------------------------------------------*\ +| AlienwareMonitorController.h | +| | +| Detector for Alienware monitors | +| | +| Adam Honse (CalcProgrammer1) 08 May 2025 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#pragma once + +#include +#include +#include + +class AlienwareMonitorController +{ +public: +AlienwareMonitorController(hid_device* dev_handle, const char* path); + ~AlienwareMonitorController(); + + std::string GetLocation(); + std::string GetSerialString(); + void SendColor(unsigned char led_id, unsigned char r, unsigned char g, unsigned char b); + +private: + hid_device* dev; + std::string location; + + void Initialize(); +}; diff --git a/Controllers/AlienwareMonitorController/AlienwareAW3423DWFControllerDetect.cpp b/Controllers/AlienwareMonitorController/AlienwareMonitorControllerDetect.cpp similarity index 60% rename from Controllers/AlienwareMonitorController/AlienwareAW3423DWFControllerDetect.cpp rename to Controllers/AlienwareMonitorController/AlienwareMonitorControllerDetect.cpp index 04387573e..d67831032 100644 --- a/Controllers/AlienwareMonitorController/AlienwareAW3423DWFControllerDetect.cpp +++ b/Controllers/AlienwareMonitorController/AlienwareMonitorControllerDetect.cpp @@ -1,6 +1,19 @@ +/*---------------------------------------------------------*\ +| AlienwareMonitorControllerDetect.cpp | +| | +| Detector for Alienware monitors | +| | +| Adam Honse (CalcProgrammer1) 08 May 2025 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + #include "Detector.h" #include "AlienwareAW3423DWFController.h" +#include "AlienwareMonitorController.h" #include "RGBController_AlienwareAW3423DWF.h" +#include "RGBController_AlienwareMonitor.h" #include /*---------------------------------------------------------*\ @@ -35,5 +48,19 @@ void DetectAlienwareAW3423DWFControllers(hid_device_info* info, const std::strin } } +void DetectAlienwareMonitorControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + AlienwareMonitorController* controller = new AlienwareMonitorController(dev, info->path); + RGBController_AlienwareMonitor* rgb_controller = new RGBController_AlienwareMonitor(controller); + rgb_controller->name = name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + REGISTER_HID_DETECTOR("Alienware AW3423DWF", DetectAlienwareAW3423DWFControllers, ALIENWARE_VID, ALIENWARE_AW3423DWF_PID); -REGISTER_HID_DETECTOR("Alienware AW3225QF", DetectAlienwareAW3423DWFControllers, ALIENWARE_VID, ALIENWARE_AW3225QF_PID); +REGISTER_HID_DETECTOR("Alienware AW3225QF", DetectAlienwareMonitorControllers, ALIENWARE_VID, ALIENWARE_AW3225QF_PID); diff --git a/Controllers/AlienwareMonitorController/RGBController_AlienwareAW3423DWF.cpp b/Controllers/AlienwareMonitorController/RGBController_AlienwareAW3423DWF.cpp index bf1c1c944..b1c94faf6 100644 --- a/Controllers/AlienwareMonitorController/RGBController_AlienwareAW3423DWF.cpp +++ b/Controllers/AlienwareMonitorController/RGBController_AlienwareAW3423DWF.cpp @@ -10,9 +10,6 @@ \*---------------------------------------------------------*/ #include "RGBController_AlienwareAW3423DWF.h" -#include - -using namespace std::chrono_literals; /**------------------------------------------------------------------*\ @name AW3423DWF @@ -22,111 +19,123 @@ using namespace std::chrono_literals; @direct :white_check_mark: @effects :x: @detectors DetectAlienwareAW3423DWFControllers - @comment The prefered way of interacting with this device is - to use the direct mode, in this mode you cannot choose the - individual LED colors (all the LED will be the same color) BUT - the frame rate of the color will be more than 3 times higher - (better for dynamic effects). However, If you still want to - individually control your LEDs set the mode to Static, here - you will be able to individually set a different color for each - LED but don't expect a frame rate higher than 1fps. + @comment \*-------------------------------------------------------------------*/ -RGBController_AlienwareAW3423DWF::RGBController_AlienwareAW3423DWF(AlienwareAW3423DWFController* controller_ptr) : - controller(controller_ptr) + +RGBController_AlienwareAW3423DWF::RGBController_AlienwareAW3423DWF(AlienwareAW3423DWFController* controller_ptr) { - name = "Alienware AW3423DWF"; - vendor = "Alienware"; - type = DEVICE_TYPE_ACCESSORY; - description = "Alienware QD-OLED Monitor"; - location = controller->GetLocation(); - serial = controller->GetSerialString(); + controller = controller_ptr; + + name = "Alienware AW3423DWF"; + vendor = "Alienware"; + type = DEVICE_TYPE_ACCESSORY; + description = "Alienware AW3423DWF Monitor Device"; + location = controller->GetLocation(); + 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; + Direct.name = "Direct"; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; modes.push_back(Direct); - mode Static; - Static.name = "Static (indivdual LED control)"; - Static.value = 1; - Static.flags = MODE_FLAG_HAS_PER_LED_COLOR; - Static.color_mode = MODE_COLORS_PER_LED; - modes.push_back(Static); + active_mode = 0; SetupZones(); } -void RGBController_AlienwareAW3423DWF::SetupZones() -{ - std::vector led_names = {"Alien", "Number", "Switch", "All"}; - - zone new_zone; - new_zone.name = "Monitor Lighting"; - new_zone.type = ZONE_TYPE_LINEAR; - new_zone.leds_min = led_names.size(); - new_zone.leds_max = led_names.size(); - new_zone.leds_count = led_names.size(); - new_zone.matrix_map = NULL; - zones.push_back(new_zone); - - for(const std::string& name : led_names) - { - led new_led; - new_led.name = name; - leds.push_back(new_led); - } - - SetupColors(); -} - -void RGBController_AlienwareAW3423DWF::DeviceUpdateLEDs() -{ - if(modes[active_mode].value == 0) - { - UpdateSingleLED(3); - } - else - { - for(unsigned int led_idx = 0; led_idx < leds.size() - 1; led_idx++) - { - UpdateSingleLED(led_idx); - std::this_thread::sleep_for(200ms); - } - } -} - -void RGBController_AlienwareAW3423DWF::UpdateSingleLED(int led) -{ - unsigned char led_id = 0x00; - - switch(led) - { - case 0: led_id = 0x01; break; - case 1: led_id = 0x02; break; - case 2: led_id = 0x08; break; - case 3: led_id = 0x0b; break; - } - - RGBColor color = colors[led]; - controller->SendColor(led_id, - RGBGetRValue(color), - RGBGetGValue(color), - RGBGetBValue(color)); -} - RGBController_AlienwareAW3423DWF::~RGBController_AlienwareAW3423DWF() { delete controller; } -void RGBController_AlienwareAW3423DWF::UpdateZoneLEDs(int zone) +void RGBController_AlienwareAW3423DWF::SetupZones() { + zone Logo; + Logo.name = "Logo"; + Logo.type = ZONE_TYPE_SINGLE; + Logo.leds_min = 1; + Logo.leds_max = 1; + Logo.leds_count = 1; + Logo.matrix_map = NULL; + zones.push_back(Logo); + + led Logo_LED; + Logo_LED.name = "Logo"; + Logo_LED.value = 0x01; + leds.push_back(Logo_LED); + + zone Number; + Number.name = "Number"; + Number.type = ZONE_TYPE_SINGLE; + Number.leds_min = 1; + Number.leds_max = 1; + Number.leds_count = 1; + Number.matrix_map = NULL; + zones.push_back(Number); + + led Number_LED; + Number_LED.name = "Number"; + Number_LED.value = 0x02; + leds.push_back(Number_LED); + + zone PowerButton; + PowerButton.name = "Power Button"; + PowerButton.type = ZONE_TYPE_SINGLE; + PowerButton.leds_min = 1; + PowerButton.leds_max = 1; + PowerButton.leds_count = 1; + PowerButton.matrix_map = NULL; + zones.push_back(PowerButton); + + led PowerButton_LED; + PowerButton_LED.name = "Power Button"; + PowerButton_LED.value = 0x08; + leds.push_back(PowerButton_LED); + + SetupColors(); +} + +void RGBController_AlienwareAW3423DWF::ResizeZone(int /*zone*/, int /*new_size*/) +{ +} + +void RGBController_AlienwareAW3423DWF::DeviceUpdateLEDs() +{ + /*-----------------------------------------------------*\ + | If all three colors are the same value, speed up the | + | direct mode by using the ALL target (0x0B) instead of | + | setting each LED individually. | + \*-----------------------------------------------------*/ + if((colors[0] == colors[1]) && (colors[1] == colors[2])) + { + unsigned char red = RGBGetRValue(colors[0]); + unsigned char grn = RGBGetGValue(colors[0]); + unsigned char blu = RGBGetBValue(colors[0]); + controller->SendColor(0x0B, red, grn, blu); + } + else + { + for(unsigned int led_idx = 0; led_idx < leds.size(); led_idx++) + { + UpdateSingleLED(led_idx); + } + } +} + +void RGBController_AlienwareAW3423DWF::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_AlienwareAW3423DWF::UpdateSingleLED(int led) +{ + unsigned char red = RGBGetRValue(colors[led]); + unsigned char grn = RGBGetGValue(colors[led]); + unsigned char blu = RGBGetBValue(colors[led]); + controller->SendColor(leds[led].value, red, grn, blu); } void RGBController_AlienwareAW3423DWF::DeviceUpdateMode() { } - -void RGBController_AlienwareAW3423DWF::ResizeZone(int, int) {} diff --git a/Controllers/AlienwareMonitorController/RGBController_AlienwareAW3423DWF.h b/Controllers/AlienwareMonitorController/RGBController_AlienwareAW3423DWF.h index eda927196..84f713e4e 100644 --- a/Controllers/AlienwareMonitorController/RGBController_AlienwareAW3423DWF.h +++ b/Controllers/AlienwareMonitorController/RGBController_AlienwareAW3423DWF.h @@ -11,23 +11,23 @@ #pragma once -#include "RGBController.h" #include "AlienwareAW3423DWFController.h" +#include "RGBController.h" class RGBController_AlienwareAW3423DWF : public RGBController { public: explicit RGBController_AlienwareAW3423DWF(AlienwareAW3423DWFController* controller_ptr); - ~RGBController_AlienwareAW3423DWF() override; + ~RGBController_AlienwareAW3423DWF(); void SetupZones(); - void ResizeZone(int zone, int new_size) override; + void ResizeZone(int zone, int new_size); - void DeviceUpdateLEDs() override; - void UpdateZoneLEDs(int zone) override; - void UpdateSingleLED(int led) override; + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); - void DeviceUpdateMode() override; + void DeviceUpdateMode(); private: AlienwareAW3423DWFController* controller; diff --git a/Controllers/AlienwareMonitorController/RGBController_AlienwareMonitor.cpp b/Controllers/AlienwareMonitorController/RGBController_AlienwareMonitor.cpp new file mode 100644 index 000000000..e8aabfe44 --- /dev/null +++ b/Controllers/AlienwareMonitorController/RGBController_AlienwareMonitor.cpp @@ -0,0 +1,143 @@ +/*---------------------------------------------------------*\ +| RGBController_AlienwareMonitor.cpp | +| | +| RGBController for Alienware monitors | +| | +| Adam Honse (CalcProgrammer1) 08 May 2025 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include "RGBController_AlienwareMonitor.h" + +/**------------------------------------------------------------------*\ + @name Alienware Monitor + @category Accessory + @type USB + @save :x: + @direct :white_check_mark: + @effects :x: + @detectors DetectAlienwareMonitorControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_AlienwareMonitor::RGBController_AlienwareMonitor(AlienwareMonitorController* controller_ptr) +{ + controller = controller_ptr; + + name = "Alienware Monitor"; + description = "Alienware Monitor"; + vendor = "Alienware"; + type = DEVICE_TYPE_ACCESSORY; + location = controller->GetLocation(); + serial = controller->GetSerialString(); + + mode Direct; + Direct.name = "Direct"; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + active_mode = 0; + + SetupZones(); +} + +RGBController_AlienwareMonitor::~RGBController_AlienwareMonitor() +{ + delete controller; +} + +void RGBController_AlienwareMonitor::SetupZones() +{ + zone Logo; + Logo.name = "Logo"; + Logo.type = ZONE_TYPE_SINGLE; + Logo.leds_min = 1; + Logo.leds_max = 1; + Logo.leds_count = 1; + Logo.matrix_map = NULL; + zones.push_back(Logo); + + led Logo_LED; + Logo_LED.name = "Logo"; + Logo_LED.value = 0x01; + leds.push_back(Logo_LED); + + zone Number; + Number.name = "Number"; + Number.type = ZONE_TYPE_SINGLE; + Number.leds_min = 1; + Number.leds_max = 1; + Number.leds_count = 1; + Number.matrix_map = NULL; + zones.push_back(Number); + + led Number_LED; + Number_LED.name = "Number"; + Number_LED.value = 0x02; + leds.push_back(Number_LED); + + zone PowerButton; + PowerButton.name = "Power Button"; + PowerButton.type = ZONE_TYPE_SINGLE; + PowerButton.leds_min = 1; + PowerButton.leds_max = 1; + PowerButton.leds_count = 1; + PowerButton.matrix_map = NULL; + zones.push_back(PowerButton); + + led PowerButton_LED; + PowerButton_LED.name = "Power Button"; + PowerButton_LED.value = 0x08; + leds.push_back(PowerButton_LED); + + SetupColors(); +} + +void RGBController_AlienwareMonitor::ResizeZone(int /*zone*/, int /*new_size*/) +{ + +} + +void RGBController_AlienwareMonitor::DeviceUpdateLEDs() +{ + /*-----------------------------------------------------*\ + | If all three colors are the same value, speed up the | + | direct mode by using the ALL target (0x0B) instead of | + | setting each LED individually. | + \*-----------------------------------------------------*/ + if((colors[0] == colors[1]) && (colors[1] == colors[2])) + { + unsigned char red = RGBGetRValue(colors[0]); + unsigned char grn = RGBGetGValue(colors[0]); + unsigned char blu = RGBGetBValue(colors[0]); + controller->SendColor(0x0B, red, grn, blu); + } + else + { + for(unsigned int led_idx = 0; led_idx < leds.size(); led_idx++) + { + UpdateSingleLED(led_idx); + } + } +} + +void RGBController_AlienwareMonitor::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_AlienwareMonitor::UpdateSingleLED(int led) +{ + unsigned char red = RGBGetRValue(colors[led]); + unsigned char grn = RGBGetGValue(colors[led]); + unsigned char blu = RGBGetBValue(colors[led]); + controller->SendColor(leds[led].value, red, grn, blu); +} + +void RGBController_AlienwareMonitor::DeviceUpdateMode() +{ + +} diff --git a/Controllers/AlienwareMonitorController/RGBController_AlienwareMonitor.h b/Controllers/AlienwareMonitorController/RGBController_AlienwareMonitor.h new file mode 100644 index 000000000..80695b7e5 --- /dev/null +++ b/Controllers/AlienwareMonitorController/RGBController_AlienwareMonitor.h @@ -0,0 +1,34 @@ +/*---------------------------------------------------------*\ +| RGBController_AlienwareMonitor.h | +| | +| RGBController for Alienware monitors | +| | +| Adam Honse (CalcProgrammer1) 08 May 2025 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "AlienwareMonitorController.h" + +class RGBController_AlienwareMonitor : public RGBController +{ +public: +RGBController_AlienwareMonitor(AlienwareMonitorController* controller_ptr); + ~RGBController_AlienwareMonitor(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: +AlienwareMonitorController* controller; +};