diff --git a/Controllers/LenovoControllers/LenovoM300Controller.cpp b/Controllers/LenovoControllers/LenovoM300Controller.cpp new file mode 100644 index 000000000..a344982a8 --- /dev/null +++ b/Controllers/LenovoControllers/LenovoM300Controller.cpp @@ -0,0 +1,86 @@ +/*-----------------------------------*\ +| LenovoM300Controller.cpp | +| | +| Controller For Lenovo Legion M300 | +| Mouse | +| | +| Wayne Riordan 9 Jan 2024 | +\*-----------------------------------*/ + +#include "LenovoM300Controller.h" +#include + +using namespace std; + +LenovoM300Controller::LenovoM300Controller(hid_device* dev_handle, const hid_device_info& info) +{ + device = dev_handle; + location = info.path; +} + +LenovoM300Controller::~LenovoM300Controller() +{ + hid_close(device); +} + +std::string LenovoM300Controller::GetDeviceLocation() +{ + return("HID: " + location); +} + +void LenovoM300Controller::SetMode(std::vector colors, unsigned char mode_value, unsigned int brigthness) +{ + unsigned char usb_buf[M300_DATA_SIZE]; + memset(usb_buf, 0x00, M300_DATA_SIZE); + + usb_buf[0x01] = 0x25; + usb_buf[0x03] = 0x01; + usb_buf[0x04] = 0x01; + usb_buf[0x05] = 0x0C; + + switch(mode_value) + { + case M300_MODE_RAINBOW: + usb_buf[0x06] = 0x01; + usb_buf[0x07] = 0x64; + usb_buf[0x09] = 0x0A; + usb_buf[0x40] = CalculateFinalByte(usb_buf, 0x0A); + break; + case M300_MODE_BREATHING: + usb_buf[0x06] = 0x02; + usb_buf[0x07] = 0x64; + usb_buf[0x09] = 0x02; + usb_buf[0x0A] = 0x03; + usb_buf[0x0C] = RGBGetRValue(colors[0]); + usb_buf[0x0D] = RGBGetGValue(colors[0]); + usb_buf[0x0E] = RGBGetBValue(colors[0]); + usb_buf[0x0F] = RGBGetRValue(colors[1]); + usb_buf[0x10] = RGBGetGValue(colors[1]); + usb_buf[0x11] = RGBGetBValue(colors[1]); + usb_buf[0x40] = CalculateFinalByte(usb_buf, 0x12); + break; + case M300_MODE_STATIC: + usb_buf[0x06] = 0x03; + usb_buf[0x07] = brigthness; + usb_buf[0x09] = RGBGetRValue(colors[0]); + usb_buf[0x0A] = RGBGetGValue(colors[0]); + usb_buf[0x0B] = RGBGetBValue(colors[0]); + usb_buf[0x40] = CalculateFinalByte(usb_buf, 0x0C); + break; + case M300_MODE_OFF: + default: + usb_buf[0x06] = 0x03; + usb_buf[0x40] = 0x36; + } + hid_write(device, usb_buf, M300_DATA_SIZE); +} + +unsigned char LenovoM300Controller::CalculateFinalByte(unsigned char* ptr, int count) +{ + unsigned char final_byte = 0; + for(int i = 0; i < count; i++) + { + final_byte += ptr[i]; + } + return final_byte; +} diff --git a/Controllers/LenovoControllers/LenovoM300Controller.h b/Controllers/LenovoControllers/LenovoM300Controller.h new file mode 100644 index 000000000..f14ced2db --- /dev/null +++ b/Controllers/LenovoControllers/LenovoM300Controller.h @@ -0,0 +1,44 @@ +/*-----------------------------------*\ +| LenovoM300Controller.h | +| | +| Header file for Lenovo M300 Mouse | +| controller | +| | +| Wayne Riordan 9 Jan 2024 | +\*-----------------------------------*/ +#pragma once + +#include "RGBController.h" +#include +#include + +#define M300_DATA_SIZE 0x41 +#define M300_MAX_BRIGTH 0x64 +#define M300_MIN_BRIGHT 0x01 + +enum +{ + M300_MODE_OFF = 0x00, + M300_MODE_RAINBOW = 0x01, + M300_MODE_BREATHING = 0x02, + M300_MODE_STATIC = 0X03 +}; + +class LenovoM300Controller +{ +public: + LenovoM300Controller(hid_device* dev_handle, const hid_device_info& info); + ~LenovoM300Controller(); + + std::string GetDeviceLocation(); + + void SetMode(std::vector colors, unsigned char mode_value, unsigned int brightness); + +protected: + hid_device* device; + +private: + std::string location; + + unsigned char CalculateFinalByte(unsigned char* ptr, int count); +}; diff --git a/Controllers/LenovoControllers/LenovoMouseDetect.cpp b/Controllers/LenovoControllers/LenovoMouseDetect.cpp new file mode 100644 index 000000000..9e4775fb7 --- /dev/null +++ b/Controllers/LenovoControllers/LenovoMouseDetect.cpp @@ -0,0 +1,36 @@ +/*-----------------------------------*\ +| LenovoMouseDetect.h | +| | +| Detect Lenovo Mouse | +| | +| Wayne Riordan 9 Jan 2024 | +\*-----------------------------------*/ + +#include "Detector.h" +#include "RGBController_LenovoM300.h" +#include "LenovoM300Controller.h" + +/*---------------------------------------------------------*\ +| Lenovo vendor, product, usage and page IDs | +\*---------------------------------------------------------*/ +#define LENOVO_VID 0x17EF +#define LEGION_M300_PID 0x60E4 +#define LENOVO_USAGE 0X01 +#define LENOVO_PAGE 0XFF01 + +void DetectLenovoLegionM300Controllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + LenovoM300Controller* controller = new LenovoM300Controller(dev, *info); + RGBController_LenovoM300* rgb_controller = new RGBController_LenovoM300(controller); + rgb_controller->name = name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + + } +} + +REGISTER_HID_DETECTOR_PU("Lenovo Legion M300", DetectLenovoLegionM300Controllers, LENOVO_VID, LEGION_M300_PID, LENOVO_PAGE, LENOVO_USAGE); diff --git a/Controllers/LenovoControllers/RGBController_LenovoM300.cpp b/Controllers/LenovoControllers/RGBController_LenovoM300.cpp new file mode 100644 index 000000000..133c4cabe --- /dev/null +++ b/Controllers/LenovoControllers/RGBController_LenovoM300.cpp @@ -0,0 +1,116 @@ +/*-----------------------------------*\ +| RGBController_LenovoM300.cpp | +| | +| RGB Controller For Lenovo M300 | +| Mouse | +| | +| Wayne Riordan 9 Jan 2024 | +\*-----------------------------------*/ +#include "RGBController_LenovoM300.h" + +/**------------------------------------------------------------------*\ + @name Lenovo Legion M300 + @category Mouse + @type USB + @save :robot: + @direct :x: + @effects :white_check_mark: + @detectors DetectLenovoLegionM300Controllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_LenovoM300::RGBController_LenovoM300(LenovoM300Controller* controller_ptr) +{ + controller = controller_ptr; + name = "Lenovo Legion M300"; + vendor = "Lenovo"; + type = DEVICE_TYPE_MOUSE; + description = name; + location = controller->GetDeviceLocation(); + + mode Static; + Static.name = "Static"; + Static.value = M300_MODE_STATIC; + Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; + Static.brightness_max = M300_MAX_BRIGTH; + Static.brightness_min = M300_MIN_BRIGHT; + Static.brightness = M300_MAX_BRIGTH; + Static.color_mode = MODE_COLORS_MODE_SPECIFIC; + Static.colors.resize(1); + modes.push_back(Static); + + mode Off; + Off.name = "Off"; + Off.value = M300_MODE_OFF; + Off.flags = MODE_FLAG_AUTOMATIC_SAVE; + Off.color_mode = MODE_COLORS_NONE; + modes.push_back(Off); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = M300_MODE_BREATHING; + Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; + Breathing.brightness_max = M300_MAX_BRIGTH; + Breathing.brightness_min = M300_MIN_BRIGHT; + Breathing.brightness = M300_MAX_BRIGTH; + Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC; + Breathing.colors.resize(2); + modes.push_back(Breathing); + + mode Spectrum; + Spectrum.name = "Spectrum Cycle"; + Spectrum.value = M300_MODE_RAINBOW; + Spectrum.flags = MODE_FLAG_AUTOMATIC_SAVE; + Spectrum.color_mode = MODE_COLORS_NONE; + modes.push_back(Spectrum); + + SetupZones(); +} + +RGBController_LenovoM300::~RGBController_LenovoM300() +{ + delete controller; +} + +void RGBController_LenovoM300::SetupZones() +{ + zone default_zone; + default_zone.name = "Mouse"; + default_zone.type = ZONE_TYPE_SINGLE; + default_zone.leds_min = 1; + default_zone.leds_max = 1; + default_zone.leds_count = 1; + default_zone.matrix_map = nullptr; + zones.emplace_back(default_zone); + + leds.resize(1); + leds[0].name = "LED 1"; + + SetupColors(); +} + +void RGBController_LenovoM300::ResizeZone(int zone, int new_size) +{ + // Not Supported +} + +void RGBController_LenovoM300::DeviceUpdateLEDs() +{ + const mode& active = modes[active_mode]; + controller->SetMode(active.colors, active.value, active.brightness); +} + +void RGBController_LenovoM300::UpdateZoneLEDs(int zone) +{ + DeviceUpdateLEDs(); +} + +void RGBController_LenovoM300::UpdateSingleLED(int led) +{ + DeviceUpdateLEDs(); +} + +void RGBController_LenovoM300::DeviceUpdateMode() +{ + DeviceUpdateLEDs(); +} diff --git a/Controllers/LenovoControllers/RGBController_LenovoM300.h b/Controllers/LenovoControllers/RGBController_LenovoM300.h new file mode 100644 index 000000000..c853b63eb --- /dev/null +++ b/Controllers/LenovoControllers/RGBController_LenovoM300.h @@ -0,0 +1,32 @@ +/*-----------------------------------*\ +| RGBController_LenovoM300.h | +| | +| Header file for Lenovo M300 Mouse | +| RGB Controller | +| | +| Wayne Riordan 9 Jan 2024 | +\*-----------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "LenovoM300Controller.h" + +class RGBController_LenovoM300 : public RGBController +{ +public: + RGBController_LenovoM300(LenovoM300Controller* controller_ptr); + ~RGBController_LenovoM300(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + LenovoM300Controller* controller; +};