/*---------------------------------------------------------*\ | HPOmen30LController.cpp | | | | Driver for HP Omen 30L | | | | This file is part of the OpenRGB project | | SPDX-License-Identifier: GPL-2.0-only | \*---------------------------------------------------------*/ #include #include #include #include "HPOmen30LController.h" #define HP_OMEN_30L_BUFFER_SIZE 58 #define HP_OMEN_30L_VERSION_ID 0x12 #define HP_OMEN_30L_MAX_BRIGHTNESS 0x64 HPOmen30LController::HPOmen30LController(hid_device* dev_handle, const char* path) { dev = dev_handle; location = path; strcpy(device_name, "HP Omen 30L"); hp_zone logo; logo.value = HP_OMEN_30L_LOGO_ZONE; logo.mode = HP_OMEN_30L_DIRECT; logo.speed = HP_OMEN_30L_SPEED_MED; logo.brightness = HP_OMEN_30L_MAX_BRIGHTNESS; hp_zones.push_back(logo); hp_zone bar; bar.value = HP_OMEN_30L_BAR_ZONE; bar.mode = HP_OMEN_30L_DIRECT; bar.speed = HP_OMEN_30L_SPEED_MED; bar.brightness = HP_OMEN_30L_MAX_BRIGHTNESS; hp_zones.push_back(bar); hp_zone fan; fan.value = HP_OMEN_30L_FAN_ZONE; fan.mode = HP_OMEN_30L_DIRECT; fan.speed = HP_OMEN_30L_SPEED_MED; fan.brightness = HP_OMEN_30L_MAX_BRIGHTNESS; hp_zones.push_back(fan); hp_zone cpu; cpu.value = HP_OMEN_30L_CPU_ZONE; cpu.mode = HP_OMEN_30L_DIRECT; cpu.speed = HP_OMEN_30L_SPEED_MED; cpu.brightness = HP_OMEN_30L_MAX_BRIGHTNESS; hp_zones.push_back(cpu); hp_zone botFan; botFan.value = HP_OMEN_30L_BOT_FAN_ZONE; botFan.mode = HP_OMEN_30L_DIRECT; botFan.speed = HP_OMEN_30L_SPEED_MED; botFan.brightness = HP_OMEN_30L_MAX_BRIGHTNESS; hp_zones.push_back(botFan); hp_zone midFan; midFan.value = HP_OMEN_30L_MID_FAN_ZONE; midFan.mode = HP_OMEN_30L_DIRECT; midFan.speed = HP_OMEN_30L_SPEED_MED; midFan.brightness = HP_OMEN_30L_MAX_BRIGHTNESS; hp_zones.push_back(midFan); hp_zone topFan; topFan.value = HP_OMEN_30L_TOP_FAN_ZONE; topFan.mode = HP_OMEN_30L_DIRECT; topFan.speed = HP_OMEN_30L_SPEED_MED; topFan.brightness = HP_OMEN_30L_MAX_BRIGHTNESS; hp_zones.push_back(topFan); } HPOmen30LController::~HPOmen30LController() { hid_close(dev); } std::string HPOmen30LController::GetLocationString() { return("HID: " + location); } char* HPOmen30LController::GetDeviceName() { return device_name; } std::string HPOmen30LController::GetSerialString() { std::string ret_string = ""; return(ret_string); } std::string HPOmen30LController::GetEffectChannelString(unsigned char /*channel*/) { std::string ret_string = ""; return(ret_string); } std::string HPOmen30LController::GetFirmwareVersionString() { std::string ret_string = ""; return(ret_string); } void HPOmen30LController::SetZoneMode(int zone,unsigned char mode, unsigned char speed,unsigned char brightness) { hp_zones[zone].mode = mode; hp_zones[zone].speed = speed; hp_zones[zone].brightness = brightness; } void HPOmen30LController::SetZoneColor(int zone, std::vector colors) { SendZoneUpdate(zone, colors); } void HPOmen30LController::SendZoneUpdate(int zone, std::vector colors) { unsigned char usb_buf[HP_OMEN_30L_BUFFER_SIZE] = {}; // zero-initialize array // 0x00 - 0x01: Unknown // 0x02: Version ID (HP_OMEN_30L_VERSION_ID) // 0x03: Lighting mode (static, direct, off, breathing, cycle, blinking, ...) // 0x04: Total color count (only different from 1 in modes with changing colors) // 0x05: Current color number (see above, used to set the different colors, one at a time, starting at 1) // 0x06 - 0x07: Unknown // 0x08 - 0x23: Used to control the RGB (static) or RGBA (direct) of the first seven LED zones // 0x24 - 0x2f: Unknown, probably also used for RGB/RGBA control if there's support up to 10 zones // 0x30: Brightness // 0x31: Type (static=0x02, direct=0x04, changing colors=0x0A) // 0x32 - 0x35: Unknown // 0x36: Zone to update (can only update one at a time) // 0x37: Power mode to update (on, suspend) // 0x38: Theme (either 0 to use the colors set in 0x04/0x05, or the ID of a predefined theme) // 0x39: Color change speed (only relevant for modes with changing colors) usb_buf[0x02] = HP_OMEN_30L_VERSION_ID; usb_buf[0x36] = hp_zones[zone].value; // The Omen controller allows setting different modes for when the computer is powered on // vs when the computer is suspended. // Because the OpenRGB UI does not allow such a choice, we're only changing the powered on mode. // If this ever changes, we need to take the user choice into consideration (HP_OMEN_30L_POWER_SUSPEND) usb_buf[0x37] = HP_OMEN_30L_POWER_ON; usb_buf[0x03] = hp_zones[zone].mode; if (hp_zones[zone].mode == HP_OMEN_30L_OFF) { hid_write(dev, usb_buf, HP_OMEN_30L_BUFFER_SIZE); return; } usb_buf[0x30] = hp_zones[zone].brightness; int index = hp_zones[zone].value - 1; if(hp_zones[zone].mode == HP_OMEN_30L_DIRECT) { usb_buf[0x31] = HP_OMEN_30L_DIRECT; usb_buf[0x04] = 0x01; usb_buf[0x05] = 0x01; usb_buf[0x08 + index * 4] = HP_OMEN_30L_MAX_BRIGHTNESS; usb_buf[0x09 + index * 4] = RGBGetRValue(colors[zone]); usb_buf[0x0A + index * 4] = RGBGetGValue(colors[zone]); usb_buf[0x0B + index * 4] = RGBGetBValue(colors[zone]); hid_write(dev, usb_buf, HP_OMEN_30L_BUFFER_SIZE); } else if(hp_zones[zone].mode == HP_OMEN_30L_STATIC) { usb_buf[0x31] = 0x02; usb_buf[0x04] = 0x01; usb_buf[0x05] = 0x01; usb_buf[0x08 + index * 3] = RGBGetRValue(colors[zone]); usb_buf[0x09 + index * 3] = RGBGetGValue(colors[zone]); usb_buf[0x0A + index * 3] = RGBGetBValue(colors[zone]); hid_write(dev, usb_buf, HP_OMEN_30L_BUFFER_SIZE); } else { usb_buf[0x31] = 0x0A; usb_buf[0x39] = hp_zones[zone].speed; // Theme is custom by default, but if we could select a theme through the UI, // we would set it in usb_buf[0x38] here and ignore the custom colors vector unsigned char theme = HP_OMEN_30L_THEME_CUSTOM; usb_buf[0x38] = theme; if (theme == HP_OMEN_30L_THEME_CUSTOM) { usb_buf[0x04] = (unsigned char)colors.size(); for(unsigned int i = 0; i < (unsigned int)colors.size(); i++) { usb_buf[0x05] = i + 1; usb_buf[0x08 + index * 3] = RGBGetRValue(colors[i]); usb_buf[0x09 + index * 3] = RGBGetGValue(colors[i]); usb_buf[0x0A + index * 3] = RGBGetBValue(colors[i]); hid_write(dev, usb_buf, HP_OMEN_30L_BUFFER_SIZE); } } else { hid_write(dev, usb_buf, HP_OMEN_30L_BUFFER_SIZE); } } }