/*-------------------------------------------------------------------*\ | CMMP750Controller.cpp | | | | Driver for Coolermaster MP750 mousepad | | | | Chris M (Dr_No) 16th Apr 2020 | | | \*-------------------------------------------------------------------*/ #include "CMMP750Controller.h" static unsigned char colour_mode_data[][6] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Off */ { 0x01, 0x04, 0xFF, 0x00, 0xFF, 0x00 }, /* Static */ { 0x02, 0x04, 0xFF, 0x00, 0xFF, 0x80 }, /* Blinking */ { 0x03, 0x04, 0xFF, 0x00, 0xFF, 0x80 }, /* Breathing */ { 0x04, 0x04, 0x80, 0x00, 0x00, 0x00 }, /* Colour Cycle */ { 0x05, 0x04, 0x80, 0x00, 0x00, 0x00 } /* Colour Breath */ }; static unsigned char speed_mode_data[9] = { 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 /* Speed Definition */ }; CMMP750Controller::CMMP750Controller(hid_device* dev_handle, char *_path) { dev = dev_handle; location = _path; const int szTemp = 256; wchar_t tmpName[szTemp]; hid_get_manufacturer_string(dev, tmpName, szTemp); std::wstring wName = std::wstring(tmpName); device_name = std::string(wName.begin(), wName.end()); hid_get_product_string(dev, tmpName, szTemp); wName = std::wstring(tmpName); device_name.append(" ").append(std::string(wName.begin(), wName.end())); hid_get_serial_number_string(dev, tmpName, szTemp); wName = std::wstring(tmpName); serial = std::string(wName.begin(), wName.end()); GetStatus(); //When setting up device get current status } CMMP750Controller::~CMMP750Controller() { hid_close(dev); } void CMMP750Controller::GetStatus() { unsigned char buffer[0x41] = { 0x00 }; int buffer_size = (sizeof(buffer) / sizeof(buffer[0])); buffer[1] = 0x07; hid_write(dev, buffer, buffer_size); hid_read(dev, buffer, buffer_size); if((buffer[0] == 0x80) && (buffer[1] == 0x05)) { current_mode = buffer[2]; current_red = buffer[3]; current_green = buffer[4]; current_blue = buffer[5]; for(int i = 0; (speed_mode_data[i] >= buffer[6] && i <= MP750_SPEED_FASTEST); i++) { current_speed = i; } } else { //Code should never reach here however just in case there is a failure set something current_mode = CM_MP750_MODE_COLOR_CYCLE; //Unicorn Spew current_red = 0xFF; current_green = 0xFF; current_blue = 0xFF; current_speed = MP750_SPEED_NORMAL; } } std::string CMMP750Controller::GetDeviceName() { return device_name; } std::string CMMP750Controller::GetSerial() { return serial; } std::string CMMP750Controller::GetLocation() { return("HID: " + location); } unsigned char CMMP750Controller::GetMode() { return current_mode; } unsigned char CMMP750Controller::GetLedRed() { return current_red; } unsigned char CMMP750Controller::GetLedGreen() { return current_green; } unsigned char CMMP750Controller::GetLedBlue() { return current_blue; } unsigned char CMMP750Controller::GetLedSpeed() { return current_speed; } void CMMP750Controller::SetMode(unsigned char mode, unsigned char speed) { current_mode = mode; current_speed = speed; SendUpdate(); } void CMMP750Controller::SetColor(unsigned char red, unsigned char green, unsigned char blue) { current_red = red; current_green = green; current_blue = blue; SendUpdate(); } void CMMP750Controller::SendUpdate() { unsigned char buffer[0x41] = { 0x00 }; int buffer_size = (sizeof(buffer) / sizeof(buffer[0])); for(std::size_t i = 0; i < CM_COLOUR_MODE_DATA_SIZE; i++) { buffer[i+1] = colour_mode_data[current_mode][i]; } if(current_mode > CM_MP750_MODE_BREATHING) { //If the mode is random colours set SPEED at BYTE2 buffer[CM_RED_BYTE] = speed_mode_data[current_speed]; } else { //Otherwise SPEED is BYTE5 buffer[CM_RED_BYTE] = current_red; buffer[CM_GREEN_BYTE] = current_green; buffer[CM_BLUE_BYTE] = current_blue; buffer[CM_SPEED_BYTE] = speed_mode_data[current_speed]; } hid_write(dev, buffer, buffer_size); }