#include "LenovoDevices.h" #include "RGBController_LenovoUSB.h" #include #include #include using namespace std; /*--------------------------------------------------------------------------------------*\ |note: the RGBController_LenovoUSB constructor determines which list of leds to pull from| \*--------------------------------------------------------------------------------------*/ /**------------------------------------------------------------------*\ @name Lenovo USB @category Keyboard @type USB @save :x: @direct :white_check_mark: @effects :x: @detectors DetectLenovoLegionUSBControllers @comment Tested on Lenovo Legion 7/7i gen. 6 ANSI and ISO models Hardware modes are not implented PLEASE UPDATE YOUR BIOS IF YOU HAVE ISSUES WITH HARDWARE MODES AFTER CLOSING OPENRGB \*-------------------------------------------------------------------*/ /*--------------------------------------------------------*\ | Legion 7 gen 6: 6 zones | | | |Note: the device has 4 zones in the protocol however, the | |vent lights have been split into 4 zones to improve ease | |of use | \*--------------------------------------------------------*/ /*------*\ |keyboard| \*------*/ lenovo_zone lenovo_legion_7_gen_6_kbd { "Keyboard", ZONE_TYPE_MATRIX, 10, 22, 0, 146, }; /*------*\ |logo | \*------*/ lenovo_zone lenovo_legion_7_gen_6_logo { "Logo", ZONE_TYPE_LINEAR, 1, 13, 147, 159, }; /*------*\ |vents | \*------*/ lenovo_zone lenovo_legion_7_gen_6_vent_left { "Left vent", ZONE_TYPE_LINEAR, 1, 26, 160, 186, }; lenovo_zone lenovo_legion_7_gen_6_vent_right { "Right vent", ZONE_TYPE_LINEAR, 1, 26, 187, 213, }; lenovo_zone lenovo_legion_7_gen_6_vent_back_right { "Back Right vent", ZONE_TYPE_LINEAR, 1, 25, 214, 239, }; lenovo_zone lenovo_legion_7_gen_6_vent_back_left { "Back Left vent", ZONE_TYPE_LINEAR, 1, 25, 240, 265, }; /*------*\ |neon | \*------*/ lenovo_zone lenovo_legion_7_gen_6_neon { "Neon", ZONE_TYPE_LINEAR, 1, 99, 266, 364, }; RGBController_LenovoUSB::RGBController_LenovoUSB(LenovoUSBController* controller_ptr) { controller = controller_ptr; mode Direct; Direct.name = "Direct"; Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; Direct.color_mode = MODE_COLORS_PER_LED; modes.push_back(Direct); name = controller->getName(); type = DEVICE_TYPE_KEYBOARD; vendor = "Lenovo"; switch(controller->getPid()) { case LEGION_7_6_PID_1: case LEGION_7_6_PID_2: case LEGION_7_6_PID_3: description = "Lenovo Legion 7 gen 6, ANSI VERSION"; lenovo_leds = legion_7_g_6_ansi_leds; lenovo_size_of_leds = sizeof(legion_7_g_6_ansi_leds)/sizeof(lenovo_led); break; } for(unsigned int i = 0; i < lenovo_size_of_leds; i++) { leds.push_back({lenovo_leds[i].name, i}); } leds.shrink_to_fit(); SetupZones(); } RGBController_LenovoUSB::~RGBController_LenovoUSB() { /*--------------------------------*\ | see LenovoUSBController.cpp for | | details | \*--------------------------------*/ controller->setDeviceHardwareMode(); delete controller; } void RGBController_LenovoUSB::SetupZones() { vector lenovo_zones; switch(controller->getPid()) { case LEGION_7_6_PID_1: case LEGION_7_6_PID_2: case LEGION_7_6_PID_3: lenovo_zones.push_back(lenovo_legion_7_gen_6_kbd); lenovo_zones.push_back(lenovo_legion_7_gen_6_logo); lenovo_zones.push_back(lenovo_legion_7_gen_6_vent_left); lenovo_zones.push_back(lenovo_legion_7_gen_6_vent_right); lenovo_zones.push_back(lenovo_legion_7_gen_6_vent_back_right); lenovo_zones.push_back(lenovo_legion_7_gen_6_vent_back_left); lenovo_zones.push_back(lenovo_legion_7_gen_6_neon); break; } for(int i = 0; i < lenovo_zones.size(); i++) { zone new_zone; new_zone.name = lenovo_zones[i].name; new_zone.type = lenovo_zones[i].type; new_zone.leds_count = lenovo_zones[i].end - lenovo_zones[i].start + 1; new_zone.leds_max = new_zone.leds_count; new_zone.leds_min = new_zone.leds_count; if(lenovo_zones[i].type == ZONE_TYPE_MATRIX) { new_zone.matrix_map = new matrix_map_type; new_zone.matrix_map->height = lenovo_zones[i].height; new_zone.matrix_map->width = lenovo_zones[i].width; new_zone.matrix_map->map = new unsigned int[new_zone.matrix_map->height * new_zone.matrix_map->width]; /*----------------------------------------------------*\ | This section sets up the maps of zones where elements| | may have an oddly aligned on the matrix | | please be sure to document in some way which zones | | in a device you may be implementing have this poperty| | (Example in the LENOVO_7_6 section bellow) | \*----------------------------------------------------*/ switch(controller->getPid()) { case LEGION_7_6_PID_1: case LEGION_7_6_PID_2: case LEGION_7_6_PID_3: /*----------------------------------------------------------------------*\ | for this device, only the keyboard map (lenovo_legion_7_gen_6_kbd) uses| | a custom map, so that map is setup here | \*----------------------------------------------------------------------*/ new_zone.matrix_map->map = new unsigned int[lenovo_zones[i].width * lenovo_zones[i].height] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, NA, NA, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, NA, NA, NA, NA, 53, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, NA, NA, 68, 69, 70, NA, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 90, 65, 91, 66, 92, 67, NA, 93, 94, 95, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, 84, 87, 86, 88, 89, 111, 113, 114, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 116, 106, 117, 107, 118, 108, 109, 110, NA, 112, NA, 115, NA, 126, 127, 128, 129, 130, NA, NA, NA, NA, 131, 132, 133, NA, NA, NA, 136, NA, NA, 119, 121, 123, 125, NA, 146, 145, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 135, NA, NA, 120, 122, 124, 144, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 134, 137, 139, NA, 140, 141, 143, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 138, NA, NA, NA, NA, 142, NA }; break; } } else { new_zone.matrix_map = NULL; } zones.push_back(new_zone); } SetupColors(); } void RGBController_LenovoUSB::ResizeZone(int /*zone*/, int /*new_size*/) { /*---------------------------------------------------------*\ | This device does not support resizing zones | \*---------------------------------------------------------*/ } void RGBController_LenovoUSB::UpdateSingleLED(int led) { if(led != NA) { controller->setSingleLED(lenovo_leds[led].zone_num, lenovo_leds[led].led_num, colors[led]); } } void RGBController_LenovoUSB::UpdateZoneLEDs(int zone) { uint8_t device_zone = lenovo_leds[zones[zone].start_idx].zone_num; vector> color_map; for(int i = 0; i < zones[zone].leds_count; i++) { int index = zones[zone].start_idx+i; color_map.push_back({lenovo_leds[index].led_num, colors[index]}); } color_map.shrink_to_fit(); controller->setZoneLeds(device_zone, color_map); } void RGBController_LenovoUSB::DeviceUpdateLEDs() { for(unsigned int i = 0; i < lenovo_size_of_leds;) { uint8_t curr_device_zone = lenovo_leds[i].zone_num; vector> curr_color_map; for(; i < lenovo_size_of_leds && lenovo_leds[i].zone_num == curr_device_zone && i < colors.size(); i++) { curr_color_map.push_back({lenovo_leds[i].led_num, colors[i]}); } controller->setZoneLeds(curr_device_zone, curr_color_map); } } void RGBController_LenovoUSB::SetCustomMode() { /*---------------------------------------------------------*\ | This device has only one mode | \*---------------------------------------------------------*/ active_mode = 0; } void RGBController_LenovoUSB::DeviceUpdateMode() { /*---------------------------------------------------------*\ | This device does not support multiple modes | \*---------------------------------------------------------*/ } void RGBController_LenovoUSB::DeviceSaveMode() { /*---------------------------------------------------------*\ | This device does not support saving or multiple modes | \*---------------------------------------------------------*/ }