/*-----------------------------------------*\ | SteelSeriesApexMController.cpp | | | | Definitions and types for SteelSeries | | Apex M750 Keyboard lighting controller | | | | Florian Heilmann (FHeilmann) 12/10/2020 | \*-----------------------------------------*/ #include "SteelSeriesApexMController.h" #include #define SS_APEX_M_PACKET_SIZE 513 #define NA 0xFF static unsigned int keys_m[] = { /* LCTRL LWIN LALT XXX SPACE XXX XXX XXX XXX RALT RWIN FNC RCTRL XXX XXX LEFT DOWN RIGHT XXX #0 XXX #. */ 79, 82, 81, NA, 40, NA, NA, NA, NA, 85, 86, 87, 83, NA, NA, 75, 76, 74, NA, 104, NA, 105, /* LSHFT Z X C V B N M , . / XXX RSHFT XXX XXX XXX UP XXX #1 #2 #3 #ENTR */ 80, 25, 23, 2, 21, 1, 13, 12, 49, 50, 51, NA, 84, NA, NA, NA, 77, NA, 95, 96, 97, 94, /* CAPLK A S D F G H J K L ; ' XXX ENTER XXX XXX XXX XXX #4 #5 #6 XXX */ 52, 0, 18, 3, 5, 6, 7, 9, 10, 11, 46, 47, NA, 36, NA, NA, NA, NA, 98, 99, 100, NA, /* TAB Q W E R T Y U I O P [ ] XXX \ DELTE END PGDN #7 #8 #9 #+ */ 39, 16, 22, 4, 17, 19, 24, 20, 8, 14, 15, 43, 44, NA, 88, 71, 72, 73, 101, 102, 103, 93, /* ` 1 2 3 4 5 6 7 8 9 0 - = XXX BKSPC INSRT HOME PGUP NUMLK #/ #* #- */ 48, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 41, 42, NA, 38, 68, 69, 70, 89, 90, 91, 92, /* ESC F1 F2 F3 F4 XXX F5 F6 F7 F8 XXX F9 F10 F11 F12 PRTSC SCRLK PAUSE XXX XXX XXX XXX */ 37, 53, 54, 55, 56, NA, 57, 58, 59, 60, NA, 61, 62, 63, 64, 65, 66, 67, NA, NA, NA, NA }; SteelSeriesApexMController::SteelSeriesApexMController(hid_device* dev_handle, steelseries_type type, const char* path) { dev = dev_handle; location = path; proto_type = type; EnableLEDControl(); } SteelSeriesApexMController::~SteelSeriesApexMController() { hid_close(dev); } void SteelSeriesApexMController::EnableLEDControl() { unsigned char buf[SS_APEX_M_PACKET_SIZE] = { 0x00 }; buf[0x00] = 0x00; buf[0x01] = 0x00; buf[0x02] = 0x00; buf[0x03] = 0x00; buf[0x04] = 0x01; buf[0x05] = 0x00; buf[0x06] = 0x85; hid_send_feature_report(dev, buf, SS_APEX_M_PACKET_SIZE); buf[0x00] = 0x00; buf[0x01] = 0x00; buf[0x02] = 0x00; buf[0x03] = 0x00; buf[0x04] = 0x03; buf[0x05] = 0x01; buf[0x06] = 0x00; buf[0x07] = 0xff; hid_send_feature_report(dev, buf, SS_APEX_M_PACKET_SIZE); buf[0x00] = 0x00; buf[0x01] = 0x00; buf[0x02] = 0x00; buf[0x03] = 0x00; buf[0x04] = 0x01; buf[0x05] = 0x00; buf[0x06] = 0x85; hid_send_feature_report(dev, buf, SS_APEX_M_PACKET_SIZE); } void SteelSeriesApexMController::SetMode(unsigned char /*mode*/, std::vector /*colors*/) { } void SteelSeriesApexMController::SetLEDsDirect(std::vector colors) { unsigned char buf[SS_APEX_M_PACKET_SIZE] = { 0x00 }; int num_keys = sizeof(keys_m) / sizeof(*keys_m); /*-----------------------------------------------------*\ | Set up Direct packet | \*-----------------------------------------------------*/ buf[0x00] = 0x00; buf[0x01] = 0x00; buf[0x02] = 0x00; buf[0x03] = 0x01; buf[0x04] = 0x8e; buf[0x05] = 0x01; buf[0x06] = 0x03; buf[0x07] = 0x06; buf[0x08] = 0x16; /*-----------------------------------------------------*\ | Fill in color data | \*-----------------------------------------------------*/ for (int i = 0; i < num_keys; i++) { if (keys_m[i] == NA) { buf[i * 3 + 9] = 0xFF; buf[i * 3 + 10] = 0x32; buf[i * 3 + 11] = 0x00; } else { buf[(i * 3) + 9] = RGBGetRValue(colors[keys_m[i]]); buf[(i * 3) + 10] = RGBGetGValue(colors[keys_m[i]]); buf[(i * 3) + 11] = RGBGetBValue(colors[keys_m[i]]); } } /*-----------------------------------------------------*\ | Send packet | \*-----------------------------------------------------*/ hid_send_feature_report(dev, buf, SS_APEX_M_PACKET_SIZE); }